Merge "Merge usb dwc3 changes backported from v3.7-rc1"
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 244e622..2103bbc 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -29,6 +29,12 @@
 - qcom,chg-ibatmax-ma:	Maximum battery charge current in mA
 - qcom,chg-ibatterm-ma:	Current at which charging is terminated in mA.
 
+Parent node optional properties:
+- qcom,chg-charging-disabled:	Set this property to disable charging
+				by default. This can then be overriden
+				writing the the module parameter
+				"charging_disabled".
+
 Sub node required structure:
 - A qcom,chg node must be a child of an SPMI node that has specified
 	the spmi-dev-container property. Each subnode reflects
diff --git a/arch/arm/boot/dts/msm-pm8019.dtsi b/arch/arm/boot/dts/msm-pm8019.dtsi
index e70eb36..2105e8a 100755
--- a/arch/arm/boot/dts/msm-pm8019.dtsi
+++ b/arch/arm/boot/dts/msm-pm8019.dtsi
@@ -152,6 +152,47 @@
 				qcom,pin-num = <6>;
 			};
 		};
+
+		pm8019_vadc: vadc@3100 {
+			compatible = "qcom,qpnp-vadc";
+			reg = <0x3100 0x100>;
+			interrupts = <0x0 0x31 0x0>;
+			qcom,adc-bit-resolution = <15>;
+			qcom,adc-vdd-reference = <1800>;
+
+			chan@8 {
+				label = "die_temp";
+				qcom,channel-num = <8>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <3>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+
+			chan@9 {
+				label = "ref_625mv";
+				qcom,channel-num = <9>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+
+			chan@10 {
+				label = "ref_1250v";
+				qcom,channel-num = <10>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+		};
 	};
 
 	qcom,pm8019@1 {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-liquid.dts
index 6be571a..6ccd933 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-liquid.dts
@@ -59,6 +59,10 @@
 		};
 	};
 
+	qcom,mdss_mdp@fd900000 {
+		qcom,memory-reservation-size = <0x1000000>; /* size 16MB */
+	};
+
 	qcom,hdmi_tx@fd922100 {
 		status = "ok";
 	};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dts b/arch/arm/boot/dts/msm8974-mtp.dts
index f75ebbe..460caf2 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-mtp.dts
@@ -180,6 +180,8 @@
 &pm8941_chg {
 	status = "ok";
 
+	qcom,chg-charging-disabled;
+
 	qcom,chg-chgr@1000 {
 		status = "ok";
 	};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 8cb7191..871c9e5 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -29,8 +29,6 @@
 	l2: cache-controller@f9040000 {
 		compatible = "arm,pl310-cache";
 		reg = <0xf9040000 0x1000>;
-		arm,data-latency = <1 1 1>;
-		arm,tag-latency = <1 1 1>;
 		cache-unified;
 		cache-level = <2>;
 	};
@@ -238,8 +236,71 @@
 		qcom,sdcc-bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50";
 		status = "disable";
 	};
+
+	qcom,bam_dmux@fc834000 {
+		compatible = "qcom,bam_dmux";
+		reg = <0xfc834000 0x7000>;
+		interrupts = <0 29 1>;
+	};
 };
 
 /include/ "msm-pm8019-rpm-regulator.dtsi"
 /include/ "msm-pm8019.dtsi"
 /include/ "msm9625-regulator.dtsi"
+
+&pm8019_vadc {
+	chan@49 {
+		label = "batt_id_therm";
+		qcom,channel-num = <49>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <0>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@51 {
+		label = "pa_therm1";
+		qcom,channel-num = <51>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <2>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@52 {
+		label = "pa_therm2";
+		qcom,channel-num = <52>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <2>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@50 {
+		label = "xo_therm";
+		qcom,channel-num = <50>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <4>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+
+	chan@60 {
+		label = "xo_therm_amux";
+		qcom,channel-num = <60>;
+		qcom,decimation = <0>;
+		qcom,pre-div-channel-scaling = <0>;
+		qcom,calibration-type = "ratiometric";
+		qcom,scale-function = <4>;
+		qcom,hw-settle-time = <0>;
+		qcom,fast-avg-setup = <0>;
+	};
+};
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 4e34ebd..0a5ec10 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -37,6 +37,8 @@
 # CONFIG_MSM_PROC_COMM is not set
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_IPC_ROUTER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 CONFIG_MSM_RPM_REGULATOR_SMD=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
 CONFIG_MSM_WATCHDOG_V2=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 8374296..10c7089 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -176,6 +176,7 @@
 	select MSM_RUN_QUEUE_STATS
 	select ARM_HAS_SG_CHAIN
 	select MSM_KRAIT_WFE_FIXUP
+	select MSM_ULTRASOUND_A
 
 config ARCH_MSM8930
 	bool "MSM8930"
@@ -202,7 +203,7 @@
 	select MSM_REMOTE_SPINLOCK_SFPB
 	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_HAS_HOLES_MEMORYMODEL
-	select MSM_ULTRASOUND
+	select MSM_ULTRASOUND_A
 	select MULTI_IRQ_HANDLER
 	select MSM_PM8X60 if PM
 	select HOLES_IN_ZONE if SPARSEMEM
@@ -235,6 +236,7 @@
 	select ARCH_SUPPORTS_MSI
 	select ARM_HAS_SG_CHAIN
 	select MSM_KRAIT_WFE_FIXUP
+	select MSM_ULTRASOUND_A
 
 config ARCH_MSM8974
 	bool "MSM8974"
@@ -355,6 +357,7 @@
 	select SMP
 	select MSM_SMP
 	select CPU_V7
+	select MSM_SCM if SMP
 	select MSM_GPIOMUX
 	select MSM_RPM_SMD
 	select MSM_NATIVE_RESTART
@@ -2337,11 +2340,15 @@
 	  for the platforms that use APRv2.
 	  Say M if you want to enable this module.
 
-config MSM_ULTRASOUND
-	bool "MSM ultrasound support"
-	depends on MSM_AUDIO_QDSP6
+config MSM_ULTRASOUND_A
+	bool "QDSP6 HW Ultrasound support"
 	help
-	  Enable support for qdsp6/ultrasound.
+          Enable HW ultrasound support in QDSP6.
+          QDSP6 can support HW encoder & decoder and
+          ultrasound processing. It will enable
+          ultrasound data paths between
+          HW and services, calculating input events
+          upon the  ultrasound data.
 
 config MSM_RPC_VIBRATOR
 	bool "RPC based MSM Vibrator Support"
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index d38396d..a386e78 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -528,7 +528,7 @@
 };
 
 /* Initialize a HFPLL at a given rate and enable it. */
-static void __init hfpll_init(struct scalable *sc,
+static void __cpuinit hfpll_init(struct scalable *sc,
 			      const struct core_speed *tgt_s)
 {
 	dev_dbg(drv.dev, "Initializing HFPLL%d\n", sc - drv.scalable);
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index b27382f..33f18a2 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -28,7 +28,6 @@
 #endif
 #include <asm/mach/map.h>
 #include <asm/hardware/gic.h>
-#include <asm/arch_timer.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
 #include <mach/board.h>
@@ -41,6 +40,7 @@
 #include <mach/socinfo.h>
 #include <mach/board.h>
 #include <mach/clk-provider.h>
+#include "board-dt.h"
 #include "clock.h"
 
 static struct clk_lookup msm_clocks_dummy[] = {
@@ -55,36 +55,10 @@
 	.size = ARRAY_SIZE(msm_clocks_dummy),
 };
 
-static struct of_device_id irq_match[] __initdata  = {
-	{ .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
-	{ .compatible = "qcom,msm-gpio", .data = msm_gpio_of_init, },
-	{}
-};
-
-static void __init msm8226_dt_timer_init(void)
-{
-	arch_timer_of_register();
-}
-
-static struct sys_timer msm8226_dt_timer = {
-	.init = msm8226_dt_timer_init
-};
-
-void __init msm8226_init_irq(void)
-{
-	of_irq_init(irq_match);
-}
-
 void __init msm8226_init(void)
 {
 	msm8226_init_gpiomux();
-
 	msm_clock_init(&msm_dummy_clock_init_data);
-}
-
-void __init msm8226_dt_init(void)
-{
-	msm8226_init();
 
 	if (socinfo_init() < 0)
 		pr_err("%s: socinfo_init() failed\n", __func__);
@@ -100,9 +74,9 @@
 
 DT_MACHINE_START(MSM8226_DT, "Qualcomm MSM 8226 (Flattened Device Tree)")
 	.map_io = msm_map_msm8226_io,
-	.init_irq = msm8226_init_irq,
-	.init_machine = msm8226_dt_init,
+	.init_irq = msm_dt_init_irq_nompm,
+	.init_machine = msm8226_init,
 	.handle_irq = gic_handle_irq,
-	.timer = &msm8226_dt_timer,
+	.timer = &msm_dt_timer,
 	.dt_compat = msm8226_dt_match,
 MACHINE_END
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 27e91ae..49f2561 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -35,6 +35,7 @@
 #include <mach/msm_memtypes.h>
 #include <mach/msm_iomap.h>
 #include <mach/msm_smd.h>
+#include <mach/scm.h>
 #include <mach/rpm-smd.h>
 #include <mach/rpm-regulator-smd.h>
 #include <mach/mpm.h>
@@ -44,6 +45,9 @@
 #include "spm.h"
 
 #define MSM_KERNEL_EBI_SIZE	0x51000
+#define SCM_SVC_L2CC_PL310	16
+#define L2CC_PL310_CTRL_ID	1
+#define L2CC_PL310_ON		1
 
 static struct memtype_reserve msm9625_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
@@ -133,7 +137,8 @@
 void __init msm9625_init_irq(void)
 {
 	struct device_node *node;
-	l2x0_of_init(L2CC_AUX_CTRL, L2X0_AUX_CTRL_MASK);
+	scm_call_atomic1(SCM_SVC_L2CC_PL310, L2CC_PL310_CTRL_ID, L2CC_PL310_ON);
+	l2x0_of_init(0, ~0UL);
 	of_irq_init(irq_match);
 	node = of_find_matching_node(NULL, mpm_match);
 
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 15a544a..3654de8 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -57,3 +57,8 @@
 	if (node)
 		of_mpm_init(node);
 }
+
+void __init msm_dt_init_irq_nompm(void)
+{
+	of_irq_init(irq_match);
+}
diff --git a/arch/arm/mach-msm/board-dt.h b/arch/arm/mach-msm/board-dt.h
index 31143a5..16a6135 100644
--- a/arch/arm/mach-msm/board-dt.h
+++ b/arch/arm/mach-msm/board-dt.h
@@ -12,3 +12,4 @@
 
 extern struct sys_timer msm_dt_timer;
 void __init msm_dt_init_irq(void);
+void __init msm_dt_init_irq_nompm(void);
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 9943812..2c49b21 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1963,6 +1963,41 @@
 	.size = ARRAY_SIZE(msm_clock_8625_dummy),
 };
 
+
+static int __init msm_gpio_config_gps(void)
+{
+	unsigned int gps_gpio = 7;
+	int ret = 0;
+
+	if (!machine_is_msm8625_evb())
+		return ret;
+
+	ret = gpio_tlmm_config(GPIO_CFG(gps_gpio, 0, GPIO_CFG_OUTPUT,
+			GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+	if (ret < 0) {
+		pr_err("gpio tlmm failed for gpio-%d\n", gps_gpio);
+		return ret;
+	}
+
+	ret = gpio_request(gps_gpio, "gnss-gpio");
+	if (ret < 0) {
+		pr_err("failed to request gpio-%d\n", gps_gpio);
+		return ret;
+	}
+
+	ret = gpio_direction_input(gps_gpio);
+	if (ret < 0) {
+		pr_err("failed to change direction for gpio-%d\n", gps_gpio);
+		return ret;
+	}
+
+	ret = gpio_export(gps_gpio, true);
+	if (ret < 0)
+		pr_err("failed to export gpio for user\n");
+
+	return ret;
+}
+
 int __init msm7x2x_misc_init(void)
 {
 	if (machine_is_msm8625_rumi3()) {
@@ -1994,6 +2029,9 @@
 
 	platform_device_register(&pl310_erp_device);
 
+	if (msm_gpio_config_gps() < 0)
+		pr_err("Error for gpio config for GPS gpio\n");
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/include/mach/msm72k_otg.h b/arch/arm/mach-msm/include/mach/msm72k_otg.h
index 623de2a..50e2936 100644
--- a/arch/arm/mach-msm/include/mach/msm72k_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm72k_otg.h
@@ -154,6 +154,7 @@
 	struct work_struct otg_resume_work;
 	struct notifier_block usbdev_nb;
 	struct msm_xo_voter *xo_handle; /*handle to vote for TCXO D1 buffer*/
+	unsigned curr_power;
 #ifdef CONFIG_USB_MSM_ACA
 	struct timer_list	id_timer;	/* drives id_status polling */
 	unsigned		b_max_power;	/* ACA: max power of accessory*/
diff --git a/arch/arm/mach-msm/include/mach/ocmem.h b/arch/arm/mach-msm/include/mach/ocmem.h
index 904de5e..cb8aae0 100644
--- a/arch/arm/mach-msm/include/mach/ocmem.h
+++ b/arch/arm/mach-msm/include/mach/ocmem.h
@@ -134,6 +134,9 @@
 int ocmem_unmap(int client_id, struct ocmem_buf *buffer,
 			struct ocmem_map_list *list);
 
+int ocmem_dump(int client_id, struct ocmem_buf *buffer,
+				unsigned long dst_phys_addr);
+
 /* Priority Enforcement APIs */
 int ocmem_evict(int client_id);
 
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
index 09dfac0..0b30c26 100644
--- a/arch/arm/mach-msm/include/mach/ocmem_priv.h
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -56,6 +56,8 @@
 	NR_TRANSFER_FAILS,
 	NR_EVICTIONS,
 	NR_RESTORES,
+	NR_DUMP_REQUESTS,
+	NR_DUMP_COMPLETE,
 	NR_OCMEM_ZSTAT_ITEMS,
 };
 
@@ -198,6 +200,7 @@
 int process_evict(int);
 int process_restore(int);
 int process_shrink(int, struct ocmem_handle *, unsigned long);
+int process_dump(int, struct ocmem_handle *, unsigned long);
 int ocmem_rdm_transfer(int, struct ocmem_map_list *,
 				unsigned long, int);
 int ocmem_clear(unsigned long, unsigned long);
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
index da639ce..22f343c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
@@ -17,20 +17,6 @@
 
 /* ======================================================================= */
 /*  Session Level commands */
-#define USM_SESSION_CMD_MEMORY_MAP			0x00012304
-struct usm_stream_cmd_memory_map {
-	struct apr_hdr	hdr;
-	u32		buf_add;
-	u32		buf_size;
-	u16		mempool_id;
-	u16		reserved;
-} __packed;
-
-#define USM_SESSION_CMD_MEMORY_UNMAP			0x00012305
-struct usm_stream_cmd_memory_unmap {
-	struct apr_hdr  hdr;
-	u32             buf_add;
-} __packed;
 
 #define USM_SESSION_CMD_RUN				0x00012306
 struct usm_stream_cmd_run {
@@ -113,31 +99,6 @@
 	u8  transp_data[USM_MAX_CFG_DATA_SIZE];
 } __packed;
 
-
-#define USM_DATA_CMD_READ				0x0001230E
-struct usm_stream_cmd_read {
-	struct apr_hdr  hdr;
-	u32                 buf_add;
-	u32                 buf_size;
-	u32                 uid;
-	u32                 counter;
-} __packed;
-
-#define USM_DATA_EVENT_READ_DONE			0x0001230F
-
-#define USM_DATA_CMD_WRITE				0x00011273
-struct usm_stream_cmd_write {
-	struct apr_hdr hdr;
-	u32 buf_add;
-	u32 buf_size;
-	u32 uid;
-	u32 msw_ts;
-	u32 lsw_ts;
-	u32 flags;
-} __packed;
-
-#define USM_DATA_EVENT_WRITE_DONE			0x00011274
-
 /* Start/stop US signal detection */
 #define USM_SESSION_CMD_SIGNAL_DETECT_MODE		0x00012719
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_a.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_a.h
new file mode 100644
index 0000000..4008698
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_a.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2012, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __APR_US_A_H__
+#define __APR_US_A_H__
+
+#include "apr_us.h"
+
+/* ======================================================================= */
+/*  Session Level commands */
+#define USM_SESSION_CMD_MEMORY_MAP			0x00012304
+struct usm_stream_cmd_memory_map {
+	struct apr_hdr	hdr;
+	u32		buf_add;
+	u32		buf_size;
+	u16		mempool_id;
+	u16		reserved;
+} __packed;
+
+#define USM_SESSION_CMD_MEMORY_UNMAP			0x00012305
+struct usm_stream_cmd_memory_unmap {
+	struct apr_hdr  hdr;
+	u32             buf_add;
+} __packed;
+
+#define USM_DATA_CMD_READ				0x0001230E
+struct usm_stream_cmd_read {
+	struct apr_hdr  hdr;
+	u32                 buf_add;
+	u32                 buf_size;
+	u32                 uid;
+	u32                 counter;
+} __packed;
+
+#define USM_DATA_EVENT_READ_DONE			0x0001230F
+
+#define USM_DATA_CMD_WRITE				0x00011273
+struct usm_stream_cmd_write {
+	struct apr_hdr hdr;
+	u32 buf_add;
+	u32 buf_size;
+	u32 uid;
+	u32 msw_ts;
+	u32 lsw_ts;
+	u32 flags;
+} __packed;
+
+#define USM_DATA_EVENT_WRITE_DONE			0x00011274
+
+#endif /* __APR_US_A_H__ */
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 5c88101..34bdc79 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -101,6 +101,7 @@
 	MSM_CPU_8064AB,
 	MSM_CPU_8930,
 	MSM_CPU_8930AA,
+	MSM_CPU_8930AB,
 	MSM_CPU_7X27AA,
 	MSM_CPU_9615,
 	MSM_CPU_8974,
@@ -342,6 +343,15 @@
 #endif
 }
 
+static inline int cpu_is_msm8930ab(void)
+{
+#ifdef CONFIG_ARCH_MSM8930
+	return read_msm_cpu_type() == MSM_CPU_8930AB;
+#else
+	return 0;
+#endif
+}
+
 static inline int cpu_is_msm8627(void)
 {
 /* 8930 and 8627 will share the same CONFIG_ARCH type unless otherwise needed */
@@ -449,7 +459,8 @@
 
 static inline int soc_class_is_msm8930(void)
 {
-	return cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627();
+	return cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8930ab() ||
+	       cpu_is_msm8627();
 }
 
 #endif
diff --git a/arch/arm/mach-msm/lpm_resources.c b/arch/arm/mach-msm/lpm_resources.c
index 2db92f3..255cd46 100644
--- a/arch/arm/mach-msm/lpm_resources.c
+++ b/arch/arm/mach-msm/lpm_resources.c
@@ -695,6 +695,10 @@
 {
 	struct msm_lpm_resource *rs = &msm_lpm_l2;
 	switch (action) {
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		rs->rs_data.value = MSM_LPM_L2_CACHE_ACTIVE;
+		break;
 	case CPU_ONLINE_FROZEN:
 	case CPU_ONLINE:
 		if (num_online_cpus() > 1)
diff --git a/arch/arm/mach-msm/ocmem.c b/arch/arm/mach-msm/ocmem.c
index 793fcc5..7829d8d 100644
--- a/arch/arm/mach-msm/ocmem.c
+++ b/arch/arm/mach-msm/ocmem.c
@@ -82,6 +82,8 @@
 	"Transfer failures",
 	"Evictions",
 	"Restorations",
+	"Dump requests",
+	"Dump completed",
 };
 
 struct ocmem_quota_table {
diff --git a/arch/arm/mach-msm/ocmem_api.c b/arch/arm/mach-msm/ocmem_api.c
index 6e094fd..689e015 100644
--- a/arch/arm/mach-msm/ocmem_api.c
+++ b/arch/arm/mach-msm/ocmem_api.c
@@ -399,6 +399,36 @@
 }
 EXPORT_SYMBOL(ocmem_unmap);
 
+int ocmem_dump(int client_id, struct ocmem_buf *buffer,
+			unsigned long dst_phys_addr)
+{
+	int ret = 0;
+	struct ocmem_handle *handle = NULL;
+
+	if (!check_id(client_id)) {
+		pr_err("ocmem: Invalid client id: %d\n", client_id);
+		return -EINVAL;
+	}
+
+	if (!zone_active(client_id)) {
+		pr_err("ocmem: Client id: %s (id: %d) not allowed to use OCMEM\n",
+					get_name(client_id), client_id);
+		return -EINVAL;
+	}
+
+	if (!buffer) {
+		pr_err("ocmem: Invalid buffer\n");
+		return -EINVAL;
+	}
+
+	handle = buffer_to_handle(buffer);
+	mutex_lock(&handle->handle_mutex);
+	ret = process_dump(client_id, handle, dst_phys_addr);
+	mutex_unlock(&handle->handle_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(ocmem_dump);
+
 unsigned long get_max_quota(int client_id)
 {
 	if (!check_id(client_id)) {
diff --git a/arch/arm/mach-msm/ocmem_sched.c b/arch/arm/mach-msm/ocmem_sched.c
index e8854d5..c380c54 100644
--- a/arch/arm/mach-msm/ocmem_sched.c
+++ b/arch/arm/mach-msm/ocmem_sched.c
@@ -65,6 +65,7 @@
 	MAX_OCMEM_PRIO = PRIO_OCMEM + 1,
 };
 
+static void __iomem *ocmem_vaddr;
 static struct list_head sched_queue[MAX_OCMEM_PRIO];
 static struct mutex sched_queue_mutex;
 
@@ -1670,6 +1671,34 @@
 	return -EINVAL;
 }
 
+static int do_dump(struct ocmem_req *req, unsigned long addr)
+{
+
+	void __iomem *req_vaddr;
+	unsigned long offset = 0x0;
+
+	down_write(&req->rw_sem);
+
+	offset = phys_to_offset(req->req_start);
+
+	req_vaddr = ocmem_vaddr + offset;
+
+	if (!req_vaddr)
+		goto err_do_dump;
+
+	pr_debug("Dumping client %s buffer ocmem p: %lx (v: %p) to ddr %lx\n",
+				get_name(req->owner), req->req_start,
+				req_vaddr, addr);
+
+	memcpy((void *)addr, req_vaddr, req->req_sz);
+
+	up_write(&req->rw_sem);
+	return 0;
+err_do_dump:
+	up_write(&req->rw_sem);
+	return -EINVAL;
+}
+
 int process_restore(int id)
 {
 	struct ocmem_req *req = NULL;
@@ -1828,6 +1857,38 @@
 	return -EINVAL;
 }
 
+int process_dump(int id, struct ocmem_handle *handle, unsigned long addr)
+{
+	struct ocmem_req *req = NULL;
+	int rc = 0;
+
+	req = handle_to_req(handle);
+
+	if (!req)
+		return -EINVAL;
+
+	if (!is_mapped(req)) {
+		pr_err("Buffer is not mapped\n");
+		goto dump_error;
+	}
+
+	inc_ocmem_stat(zone_of(req), NR_DUMP_REQUESTS);
+
+	mutex_lock(&sched_mutex);
+	rc = do_dump(req, addr);
+	mutex_unlock(&sched_mutex);
+
+	if (rc < 0)
+		goto dump_error;
+
+	inc_ocmem_stat(zone_of(req), NR_DUMP_COMPLETE);
+	return 0;
+
+dump_error:
+	pr_err("Dumping OCMEM memory failed for client %d\n", id);
+	return -EINVAL;
+}
+
 static void ocmem_sched_wk_func(struct work_struct *work)
 {
 
@@ -1906,6 +1967,7 @@
 	pdata = platform_get_drvdata(pdev);
 	mutex_init(&sched_mutex);
 	mutex_init(&sched_queue_mutex);
+	ocmem_vaddr = pdata->vbase;
 	for (i = MIN_PRIO; i < MAX_OCMEM_PRIO; i++)
 		INIT_LIST_HEAD(&sched_queue[i]);
 
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 5c40750..f55d509 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1071,7 +1071,7 @@
 
 	msm_pc_debug_counters_phys = res->start;
 	WARN_ON(resource_size(res) < SZ_64);
-	msm_pc_debug_counters = devm_ioremap(&pdev->dev, res->start,
+	msm_pc_debug_counters = devm_ioremap_nocache(&pdev->dev, res->start,
 					resource_size(res));
 
 	if (!msm_pc_debug_counters)
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index ed8cb345..3731722 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -25,5 +25,5 @@
 obj-$(CONFIG_MSM_QDSP6V2_CODECS) += rtac_v2.o q6audio_v2.o q6audio_v2_aio.o
 obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
 obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o
-obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/
+obj-$(CONFIG_MSM_ULTRASOUND_A) += ultrasound/version_a/
 obj-m += adsprpc.o
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
deleted file mode 100644
index 0be1303..0000000
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-y += q6usm.o usf.o usfcdev.o
-EXTRA_CFLAGS += -I$(src)/..
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
index 1fe71bf..c68ad68 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
@@ -15,6 +15,11 @@
 
 #include <mach/qdsp6v2/apr_us.h>
 
+#define Q6USM_EVENT_UNDEF                0
+#define Q6USM_EVENT_READ_DONE            1
+#define Q6USM_EVENT_WRITE_DONE           2
+#define Q6USM_EVENT_SIGNAL_DETECT_RESULT 3
+
 /* cyclic buffer with 1 gap support */
 #define USM_MIN_BUF_CNT 3
 
@@ -39,16 +44,6 @@
 /* bit 4 represents META enable of encoded data buffer */
 #define BUFFER_META_ENABLE	0x0010
 
-struct us_region {
-	dma_addr_t	phys;
-	/* If == NULL, the region isn't allocated */
-	void		*data;
-	/* number of buffers in the region */
-	uint32_t	buf_cnt;
-	/* size of buffer */
-	uint32_t	buf_size;
-};
-
 struct us_port_data {
 	dma_addr_t	phys;
 	/* cyclic region of buffers with 1 gap */
@@ -57,15 +52,17 @@
 	uint32_t	buf_cnt;
 	/* size of buffer */
 	uint32_t	buf_size;
-	/* TX: write index */
+	/* write index */
 	uint32_t	dsp_buf;
-	/* TX: read index */
+	/* read index */
 	uint32_t	cpu_buf;
 	/* expected token from dsp */
 	uint32_t	expected_token;
 	/* read or write locks */
 	struct mutex	lock;
 	spinlock_t	dsp_lock;
+	/* extended parameters, related to q6 variants */
+	void			*ext;
 };
 
 struct us_client {
@@ -97,19 +94,11 @@
 	void *priv);
 int q6usm_open_read(struct us_client *usc, uint32_t format);
 void q6usm_us_client_free(struct us_client *usc);
-int q6usm_memory_map(struct us_client *usc, uint32_t buf_add,
-		     int dir, uint32_t bufsz, uint32_t bufcnt);
-int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add,
-		       int dir);
-
-uint32_t q6usm_get_ready_data(int dir, struct us_client *usc);
 uint32_t q6usm_get_virtual_address(int dir, struct us_client *usc,
 				   struct vm_area_struct *vms);
-
 int q6usm_open_write(struct us_client *usc,  uint32_t format);
 int q6usm_write(struct us_client *usc, uint32_t write_ind);
-bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t* free_region);
-
+bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t *free_region);
 int q6usm_set_us_detection(struct us_client *usc,
 			   struct usm_session_cmd_detect_info *detect_info,
 			   uint16_t detect_info_size);
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index a973b92..d00eae8 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -27,8 +27,8 @@
 #include "usfcdev.h"
 
 /* The driver version*/
-#define DRV_VERSION "1.4.0"
-#define USF_VERSION_ID 0x0140
+#define DRV_VERSION "1.4.1"
+#define USF_VERSION_ID 0x0141
 
 /* Standard timeout in the asynchronous ops */
 #define USF_TIMEOUT_JIFFIES (1*HZ) /* 1 sec */
@@ -351,7 +351,7 @@
 	}
 
 	switch (opcode) {
-	case USM_DATA_EVENT_WRITE_DONE:
+	case Q6USM_EVENT_WRITE_DONE:
 		wake_up(&usf_xx->wait);
 		break;
 	default:
@@ -370,14 +370,14 @@
 	}
 
 	switch (opcode) {
-	case USM_DATA_EVENT_READ_DONE:
+	case Q6USM_EVENT_READ_DONE:
 		if (token == USM_WRONG_TOKEN)
 			usf_xx->usf_state = USF_ERROR_STATE;
 		usf_xx->new_region = token;
 		wake_up(&usf_xx->wait);
 		break;
 
-	case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT:
+	case Q6USM_EVENT_SIGNAL_DETECT_RESULT:
 		usf_xx->us_detect_type = (payload[APR_US_DETECT_RESULT_IND]) ?
 					USF_US_DETECT_YES :
 					USF_US_DETECT_NO;
@@ -1043,8 +1043,7 @@
 
 	if ((usf_xx->usf_state != USF_WORK_STATE) ||
 	    (rc == -ERESTARTSYS)) {
-		pr_err("%s: Getting ready region failed "
-			"work state[%d]; rc[%d]\n",
+		pr_err("%s: Get ready region failure; state[%d]; rc[%d]\n",
 		       __func__, usf_xx->usf_state, rc);
 		return -EINTR;
 	}
@@ -1459,4 +1458,3 @@
 device_initcall(usf_init);
 
 MODULE_DESCRIPTION("Ultrasound framework driver");
-MODULE_VERSION(DRV_VERSION);
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/Makefile
new file mode 100644
index 0000000..38d7d51
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/Makefile
@@ -0,0 +1,2 @@
+obj-y += q6usm_a.o ../usf.o ../usfcdev.o
+ccflags-y := -I$(src)/.. -I$(src)/../..
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
similarity index 96%
rename from arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
rename to arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
index dce3812..5d30eb1 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -19,11 +19,9 @@
 #include <linux/slab.h>
 #include <linux/msm_audio.h>
 #include <sound/apr_audio.h>
+#include <mach/qdsp6v2/apr_us_a.h>
 #include "q6usm.h"
 
-/* The driver version*/
-#define DRV_VERSION "1.2"
-
 #define SESSION_MAX 0x02 /* aDSP:USM limit */
 
 #define READDONE_IDX_STATUS     0
@@ -58,6 +56,96 @@
 
 static struct usm_mmap this_mmap;
 
+static void q6usm_add_mmaphdr(struct us_client *usc, struct apr_hdr *hdr,
+			      uint32_t pkt_size, bool cmd_flg)
+{
+	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
+				       APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	hdr->src_port = 0;
+	hdr->dest_port = 0;
+	if (cmd_flg) {
+		hdr->token = 0;
+		atomic_set(&this_mmap.cmd_state, 1);
+	}
+	hdr->pkt_size  = pkt_size;
+	return;
+}
+
+static int q6usm_memory_map(struct us_client *usc, uint32_t buf_add, int dir,
+		     uint32_t bufsz, uint32_t bufcnt)
+{
+	struct usm_stream_cmd_memory_map mem_map;
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_mmaphdr(usc, &mem_map.hdr,
+			  sizeof(struct usm_stream_cmd_memory_map), true);
+	mem_map.hdr.opcode = USM_SESSION_CMD_MEMORY_MAP;
+
+	mem_map.buf_add = buf_add;
+	mem_map.buf_size = bufsz * bufcnt;
+	mem_map.mempool_id = 0;
+
+	pr_debug("%s: buf add[%x]  buf_add_parameter[%x]\n",
+		 __func__, mem_map.buf_add, buf_add);
+
+	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_map);
+	if (rc < 0) {
+		pr_err("%s: mem_map op[0x%x]rc[%d]\n",
+		       __func__, mem_map.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(this_mmap.cmd_wait,
+				(atomic_read(&this_mmap.cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for memory_map\n", __func__);
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add, int dir)
+{
+	struct usm_stream_cmd_memory_unmap mem_unmap;
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_mmaphdr(usc, &mem_unmap.hdr,
+			  sizeof(struct usm_stream_cmd_memory_unmap), true);
+	mem_unmap.hdr.opcode = USM_SESSION_CMD_MEMORY_UNMAP;
+	mem_unmap.buf_add = buf_add;
+
+	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
+	if (rc < 0) {
+		pr_err("%s:mem_unmap op[0x%x]rc[%d]\n",
+		       __func__, mem_unmap.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(this_mmap.cmd_wait,
+				(atomic_read(&this_mmap.cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for memory_map\n", __func__);
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
 static int q6usm_session_alloc(struct us_client *usc)
 {
 	int ind = 0;
@@ -276,10 +364,11 @@
 	uint32_t token;
 	uint32_t *payload = data->payload;
 
-	pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x];"
-		 "token[0x%x]; payload_s[%d]; src[%d]; dest[%d];\n",
-		 __func__, payload[0], payload[1], data->opcode, data->token,
-		 data->payload_size, data->src_port, data->dest_port);
+	pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n",
+		 __func__, payload[0], payload[1], data->opcode);
+	pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n",
+		 __func__, data->token, data->payload_size,
+		 data->src_port, data->dest_port);
 
 	if (data->opcode == APR_BASIC_RSP_RESULT) {
 		/* status field check */
@@ -315,6 +404,7 @@
 	unsigned long dsp_flags;
 	uint32_t *payload = data->payload;
 	uint32_t token = data->token;
+	uint32_t opcode = Q6USM_EVENT_UNDEF;
 
 	if (usc == NULL) {
 		pr_err("%s: client info is NULL\n", __func__);
@@ -363,6 +453,7 @@
 	case USM_DATA_EVENT_READ_DONE: {
 		struct us_port_data *port = &usc->port[OUT];
 
+		opcode = Q6USM_EVENT_READ_DONE;
 		spin_lock_irqsave(&port->dsp_lock, dsp_flags);
 		if (payload[READDONE_IDX_STATUS]) {
 			pr_err("%s: wrong READDONE[%d]; token[%d]\n",
@@ -408,6 +499,7 @@
 	case USM_DATA_EVENT_WRITE_DONE: {
 		struct us_port_data *port = &usc->port[IN];
 
+		opcode = Q6USM_EVENT_WRITE_DONE;
 		if (payload[WRITEDONE_IDX_STATUS]) {
 			pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n",
 			       __func__,
@@ -428,6 +520,7 @@
 		pr_debug("%s: US detect result: result=%d",
 			 __func__,
 			 payload[0]);
+		opcode = Q6USM_EVENT_SIGNAL_DETECT_RESULT;
 
 		break;
 	} /* case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT */
@@ -438,21 +531,12 @@
 	} /* switch */
 
 	if (usc->cb)
-		usc->cb(data->opcode, token,
+		usc->cb(opcode, token,
 			data->payload, usc->priv);
 
 	return 0;
 }
 
-uint32_t q6usm_get_ready_data(int dir, struct us_client *usc)
-{
-	uint32_t ret = 0xffffffff;
-
-	if ((usc != NULL) && ((dir == IN) || (dir == OUT)))
-		ret = usc->port[dir].dsp_buf;
-	return ret;
-}
-
 uint32_t q6usm_get_virtual_address(int dir,
 				   struct us_client *usc,
 				   struct vm_area_struct *vms)
@@ -490,21 +574,6 @@
 	return;
 }
 
-static void q6usm_add_mmaphdr(struct us_client *usc, struct apr_hdr *hdr,
-			      uint32_t pkt_size, bool cmd_flg)
-{
-	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
-				       APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
-	hdr->src_port = 0;
-	hdr->dest_port = 0;
-	if (cmd_flg) {
-		hdr->token = 0;
-		atomic_set(&this_mmap.cmd_state, 1);
-	}
-	hdr->pkt_size  = pkt_size;
-	return;
-}
-
 static uint32_t q6usm_ext2int_format(uint32_t ext_format)
 {
 	uint32_t int_format = INVALID_FORMAT;
@@ -573,7 +642,7 @@
 }
 
 
-int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg* us_cfg)
+int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg)
 {
 	uint32_t int_format = INVALID_FORMAT;
 	struct usm_stream_cmd_encdec_cfg_blk  enc_cfg_obj;
@@ -849,80 +918,6 @@
 }
 
 
-int q6usm_memory_map(struct us_client *usc, uint32_t buf_add, int dir,
-		     uint32_t bufsz, uint32_t bufcnt)
-{
-	struct usm_stream_cmd_memory_map mem_map;
-	int rc = 0;
-
-	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
-		pr_err("%s: APR handle NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	q6usm_add_mmaphdr(usc, &mem_map.hdr,
-			  sizeof(struct usm_stream_cmd_memory_map), true);
-	mem_map.hdr.opcode = USM_SESSION_CMD_MEMORY_MAP;
-
-	mem_map.buf_add = buf_add;
-	mem_map.buf_size = bufsz * bufcnt;
-	mem_map.mempool_id = 0;
-
-	pr_debug("%s: buf add[%x]  buf_add_parameter[%x]\n",
-		 __func__, mem_map.buf_add, buf_add);
-
-	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_map);
-	if (rc < 0) {
-		pr_err("%s: mem_map op[0x%x]rc[%d]\n",
-		       __func__, mem_map.hdr.opcode, rc);
-		goto fail_cmd;
-	}
-
-	rc = wait_event_timeout(this_mmap.cmd_wait,
-				(atomic_read(&this_mmap.cmd_state) == 0),
-				Q6USM_TIMEOUT_JIFFIES);
-	if (!rc) {
-		rc = -ETIME;
-		pr_err("%s: timeout. waited for memory_map\n", __func__);
-	} else
-		rc = 0;
-fail_cmd:
-	return rc;
-}
-
-int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add, int dir)
-{
-	struct usm_stream_cmd_memory_unmap mem_unmap;
-	int rc = 0;
-
-	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
-		pr_err("%s: APR handle NULL\n", __func__);
-		return -EINVAL;
-	}
-
-	q6usm_add_mmaphdr(usc, &mem_unmap.hdr,
-			  sizeof(struct usm_stream_cmd_memory_unmap), true);
-	mem_unmap.hdr.opcode = USM_SESSION_CMD_MEMORY_UNMAP;
-	mem_unmap.buf_add = buf_add;
-
-	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
-	if (rc < 0) {
-		pr_err("%s:mem_unmap op[0x%x]rc[%d]\n",
-		       __func__, mem_unmap.hdr.opcode, rc);
-		goto fail_cmd;
-	}
-
-	rc = wait_event_timeout(this_mmap.cmd_wait,
-				(atomic_read(&this_mmap.cmd_state) == 0),
-				Q6USM_TIMEOUT_JIFFIES);
-	if (!rc) {
-		rc = -ETIME;
-		pr_err("%s: timeout. waited for memory_map\n", __func__);
-	} else
-		rc = 0;
-fail_cmd:
-	return rc;
-}
 
 int q6usm_read(struct us_client *usc, uint32_t read_ind)
 {
@@ -1057,7 +1052,7 @@
 	return rc;
 }
 
-bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t* free_region)
+bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t *free_region)
 {
 	struct us_port_data *port = NULL;
 	u32 cpu_buf = 0;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 0beb952..b865daa 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -296,6 +296,12 @@
 	/* 8064AB IDs */
 	[153] = MSM_CPU_8064AB,
 
+	/* 8930AB IDs */
+	[154] = MSM_CPU_8930AB,
+	[155] = MSM_CPU_8930AB,
+	[156] = MSM_CPU_8930AB,
+	[157] = MSM_CPU_8930AB
+
 	/* Uninitialized IDs are not known to run Linux.
 	   MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
 	   considered as unknown CPU. */
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index bae1ab0..a58f2ab 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -40,12 +40,68 @@
 
 #include "smd_private.h"
 
+/**
+ * enum p_subsys_state - state of a subsystem (private)
+ * @SUBSYS_NORMAL: subsystem is operating normally
+ * @SUBSYS_CRASHED: subsystem has crashed and hasn't been shutdown
+ * @SUBSYS_RESTARTING: subsystem has been shutdown and is now restarting
+ *
+ * The 'private' side of the subsytem state used to determine where in the
+ * restart process the subsystem is.
+ */
+enum p_subsys_state {
+	SUBSYS_NORMAL,
+	SUBSYS_CRASHED,
+	SUBSYS_RESTARTING,
+};
+
+/**
+ * enum subsys_state - state of a subsystem (public)
+ * @SUBSYS_OFFLINE: subsystem is offline
+ * @SUBSYS_ONLINE: subsystem is online
+ *
+ * The 'public' side of the subsytem state, exposed to userspace.
+ */
+enum subsys_state {
+	SUBSYS_OFFLINE,
+	SUBSYS_ONLINE,
+};
+
+static const char * const subsys_states[] = {
+	[SUBSYS_OFFLINE] = "OFFLINE",
+	[SUBSYS_ONLINE] = "ONLINE",
+};
+
+/**
+ * struct subsys_tracking - track state of a subsystem or restart order
+ * @p_state: private state of subsystem/order
+ * @state: public state of subsystem/order
+ * @s_lock: protects p_state
+ * @lock: protects subsystem/order callbacks and state
+ *
+ * Tracks the state of a subsystem or a set of subsystems (restart order).
+ * Doing this avoids the need to grab each subsystem's lock and update
+ * each subsystems state when restarting an order.
+ */
+struct subsys_tracking {
+	enum p_subsys_state p_state;
+	spinlock_t s_lock;
+	enum subsys_state state;
+	struct mutex lock;
+};
+
+/**
+ * struct subsys_soc_restart_order - subsystem restart order
+ * @subsystem_list: names of subsystems in this restart order
+ * @count: number of subsystems in order
+ * @track: state tracking and locking
+ * @subsys_ptrs: pointers to subsystems in this restart order
+ */
 struct subsys_soc_restart_order {
 	const char * const *subsystem_list;
 	int count;
 
-	struct mutex shutdown_lock;
-	struct mutex powerup_lock;
+	struct subsys_tracking track;
 	struct subsys_device *subsys_ptrs[];
 };
 
@@ -55,36 +111,34 @@
 	struct list_head list;
 };
 
-enum subsys_state {
-	SUBSYS_OFFLINE,
-	SUBSYS_ONLINE,
-	SUBSYS_CRASHED,
-};
-
-static const char * const subsys_states[] = {
-	[SUBSYS_OFFLINE] = "OFFLINE",
-	[SUBSYS_ONLINE] = "ONLINE",
-	[SUBSYS_CRASHED] = "CRASHED",
-};
-
+/**
+ * struct subsys_device - subsystem device
+ * @desc: subsystem descriptor
+ * @wake_lock: prevents suspend during subsystem_restart()
+ * @wlname: name of @wake_lock
+ * @work: context for subsystem_restart_wq_func() for this device
+ * @track: state tracking and locking
+ * @notify: subsys notify handle
+ * @dev: device
+ * @owner: module that provides @desc
+ * @count: reference count of subsystem_get()/subsystem_put()
+ * @id: ida
+ * @restart_order: order of other devices this devices restarts with
+ * @dentry: debugfs directory for this device
+ */
 struct subsys_device {
 	struct subsys_desc *desc;
 	struct wake_lock wake_lock;
 	char wlname[64];
 	struct work_struct work;
-	spinlock_t restart_lock;
-	bool restarting;
+
+	struct subsys_tracking track;
 
 	void *notify;
 	struct device dev;
 	struct module *owner;
 	int count;
-	enum subsys_state state;
 	int id;
-
-	struct mutex shutdown_lock;
-	struct mutex powerup_lock;
-
 	void *restart_order;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *dentry;
@@ -105,7 +159,7 @@
 static ssize_t state_show(struct device *dev, struct device_attribute *attr,
 		char *buf)
 {
-	enum subsys_state state = to_subsys(dev)->state;
+	enum subsys_state state = to_subsys(dev)->track.state;
 	return snprintf(buf, PAGE_SIZE, "%s\n", subsys_states[state]);
 }
 
@@ -114,14 +168,14 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&subsys->restart_lock, flags);
-	if (subsys->state != state) {
-		subsys->state = state;
-		spin_unlock_irqrestore(&subsys->restart_lock, flags);
+	spin_lock_irqsave(&subsys->track.s_lock, flags);
+	if (subsys->track.state != state) {
+		subsys->track.state = state;
+		spin_unlock_irqrestore(&subsys->track.s_lock, flags);
 		sysfs_notify(&subsys->dev.kobj, NULL, "state");
 		return;
 	}
-	spin_unlock_irqrestore(&subsys->restart_lock, flags);
+	spin_unlock_irqrestore(&subsys->track.s_lock, flags);
 }
 
 static struct device_attribute subsys_attrs[] = {
@@ -396,56 +450,27 @@
 						struct subsys_device, work);
 	struct subsys_device **list;
 	struct subsys_desc *desc = dev->desc;
-	struct subsys_soc_restart_order *soc_restart_order = NULL;
-	struct mutex *powerup_lock;
-	struct mutex *shutdown_lock;
+	struct subsys_soc_restart_order *order = dev->restart_order;
+	struct subsys_tracking *track;
 	unsigned count;
 	unsigned long flags;
 
-	if (restart_level != RESET_SUBSYS_INDEPENDENT)
-		soc_restart_order = dev->restart_order;
-
 	/*
 	 * It's OK to not take the registration lock at this point.
 	 * This is because the subsystem list inside the relevant
 	 * restart order is not being traversed.
 	 */
-	if (!soc_restart_order) {
+	if (restart_level != RESET_SUBSYS_INDEPENDENT && order) {
+		list = order->subsys_ptrs;
+		count = order->count;
+		track = &order->track;
+	} else {
 		list = &dev;
 		count = 1;
-		powerup_lock = &dev->powerup_lock;
-		shutdown_lock = &dev->shutdown_lock;
-	} else {
-		list = soc_restart_order->subsys_ptrs;
-		count = soc_restart_order->count;
-		powerup_lock = &soc_restart_order->powerup_lock;
-		shutdown_lock = &soc_restart_order->shutdown_lock;
+		track = &dev->track;
 	}
 
-	pr_debug("[%p]: Attempting to get shutdown lock!\n", current);
-
-	/*
-	 * Try to acquire shutdown_lock. If this fails, these subsystems are
-	 * already being restarted - return.
-	 */
-	if (!mutex_trylock(shutdown_lock))
-		goto out;
-
-	pr_debug("[%p]: Attempting to get powerup lock!\n", current);
-
-	/*
-	 * Now that we've acquired the shutdown lock, either we're the first to
-	 * restart these subsystems or some other thread is doing the powerup
-	 * sequence for these subsystems. In the latter case, panic and bail
-	 * out, since a subsystem died in its powerup sequence. This catches
-	 * the case where a subsystem in a restart order isn't the one
-	 * who initiated the original restart but has crashed while the restart
-	 * order is being rebooted.
-	 */
-	if (!mutex_trylock(powerup_lock))
-		panic("%s[%p]: Subsystem died during powerup!",
-						__func__, current);
-
+	mutex_lock(&track->lock);
 	do_epoch_check(dev);
 
 	/*
@@ -461,13 +486,9 @@
 	for_each_subsys_device(list, count, NULL, subsystem_shutdown);
 	send_notification_to_order(list, count, SUBSYS_AFTER_SHUTDOWN);
 
-	/*
-	 * Now that we've finished shutting down these subsystems, release the
-	 * shutdown lock. If a subsystem restart request comes in for a
-	 * subsystem in _this_ restart order after the unlock below, and
-	 * before the powerup lock is released, panic and bail out.
-	 */
-	mutex_unlock(shutdown_lock);
+	spin_lock_irqsave(&track->s_lock, flags);
+	track->p_state = SUBSYS_RESTARTING;
+	spin_unlock_irqrestore(&track->s_lock, flags);
 
 	/* Collect ram dumps for all subsystems in order here */
 	for_each_subsys_device(list, count, NULL, subsystem_ramdump);
@@ -479,44 +500,46 @@
 	pr_info("[%p]: Restart sequence for %s completed.\n",
 			current, desc->name);
 
-	mutex_unlock(powerup_lock);
-
 	mutex_unlock(&soc_order_reg_lock);
+	mutex_unlock(&track->lock);
 
-	pr_debug("[%p]: Released powerup lock!\n", current);
-
-out:
-	spin_lock_irqsave(&dev->restart_lock, flags);
-	dev->restarting = false;
+	spin_lock_irqsave(&track->s_lock, flags);
+	track->p_state = SUBSYS_NORMAL;
 	wake_unlock(&dev->wake_lock);
-	spin_unlock_irqrestore(&dev->restart_lock, flags);
+	spin_unlock_irqrestore(&track->s_lock, flags);
 }
 
 static void __subsystem_restart_dev(struct subsys_device *dev)
 {
 	struct subsys_desc *desc = dev->desc;
 	const char *name = dev->desc->name;
+	struct subsys_soc_restart_order *order = dev->restart_order;
+	struct subsys_tracking *track;
 	unsigned long flags;
 
+	if (restart_level != RESET_SUBSYS_INDEPENDENT && order)
+		track = &order->track;
+	else
+		track = &dev->track;
+
 	pr_debug("Restarting %s [level=%d]!\n", desc->name, restart_level);
 
 	/*
-	 * We want to allow drivers to call subsystem_restart{_dev}() as many
-	 * times as they want up until the point where the subsystem is
-	 * shutdown.
+	 * Allow drivers to call subsystem_restart{_dev}() as many times as
+	 * they want up until the point where the subsystem is shutdown.
 	 */
-	spin_lock_irqsave(&dev->restart_lock, flags);
-	if (dev->state != SUBSYS_CRASHED) {
-		if (dev->state == SUBSYS_ONLINE && !dev->restarting) {
-			dev->restarting = true;
-			dev->state = SUBSYS_CRASHED;
+	spin_lock_irqsave(&track->s_lock, flags);
+	if (track->p_state != SUBSYS_CRASHED) {
+		if (dev->track.state == SUBSYS_ONLINE &&
+		    track->p_state != SUBSYS_RESTARTING) {
+			track->p_state = SUBSYS_CRASHED;
 			wake_lock(&dev->wake_lock);
 			queue_work(ssr_wq, &dev->work);
 		} else {
 			panic("Subsystem %s crashed during SSR!", name);
 		}
 	}
-	spin_unlock_irqrestore(&dev->restart_lock, flags);
+	spin_unlock_irqrestore(&track->s_lock, flags);
 }
 
 int subsystem_restart_dev(struct subsys_device *dev)
@@ -650,8 +673,7 @@
 	struct subsys_device *subsys = to_subsys(dev);
 
 	wake_lock_destroy(&subsys->wake_lock);
-	mutex_destroy(&subsys->shutdown_lock);
-	mutex_destroy(&subsys->powerup_lock);
+	mutex_destroy(&subsys->track.lock);
 	ida_simple_remove(&subsys_ida, subsys->id);
 	kfree(subsys);
 }
@@ -670,7 +692,7 @@
 	subsys->dev.parent = desc->dev;
 	subsys->dev.bus = &subsys_bus_type;
 	subsys->dev.release = subsys_device_release;
-	subsys->state = SUBSYS_ONLINE; /* Until proper refcounting appears */
+	subsys->track.state = SUBSYS_ONLINE; /* Until proper refcounting */
 
 	subsys->notify = subsys_notif_add_subsys(desc->name);
 	subsys->restart_order = update_restart_order(subsys);
@@ -678,7 +700,7 @@
 	snprintf(subsys->wlname, sizeof(subsys->wlname), "ssr(%s)", desc->name);
 	wake_lock_init(&subsys->wake_lock, WAKE_LOCK_SUSPEND, subsys->wlname);
 	INIT_WORK(&subsys->work, subsystem_restart_wq_func);
-	spin_lock_init(&subsys->restart_lock);
+	spin_lock_init(&subsys->track.s_lock);
 
 	subsys->id = ida_simple_get(&subsys_ida, 0, 0, GFP_KERNEL);
 	if (subsys->id < 0) {
@@ -687,8 +709,7 @@
 	}
 	dev_set_name(&subsys->dev, "subsys%d", subsys->id);
 
-	mutex_init(&subsys->shutdown_lock);
-	mutex_init(&subsys->powerup_lock);
+	mutex_init(&subsys->track.lock);
 
 	ret = subsys_debugfs_add(subsys);
 	if (ret)
@@ -705,8 +726,7 @@
 err_register:
 	subsys_debugfs_remove(subsys);
 err_debugfs:
-	mutex_destroy(&subsys->shutdown_lock);
-	mutex_destroy(&subsys->powerup_lock);
+	mutex_destroy(&subsys->track.lock);
 	ida_simple_remove(&subsys_ida, subsys->id);
 err_ida:
 	wake_lock_destroy(&subsys->wake_lock);
@@ -721,10 +741,10 @@
 		return;
 
 	if (get_device(&subsys->dev)) {
-		mutex_lock(&subsys->powerup_lock);
+		mutex_lock(&subsys->track.lock);
 		WARN_ON(subsys->count);
 		device_unregister(&subsys->dev);
-		mutex_unlock(&subsys->powerup_lock);
+		mutex_unlock(&subsys->track.lock);
 		subsys_debugfs_remove(subsys);
 		put_device(&subsys->dev);
 	}
@@ -760,13 +780,13 @@
 
 	if (cpu_is_msm8x60()) {
 		for (i = 0; i < ARRAY_SIZE(orders_8x60_all); i++) {
-			mutex_init(&orders_8x60_all[i]->powerup_lock);
-			mutex_init(&orders_8x60_all[i]->shutdown_lock);
+			mutex_init(&orders_8x60_all[i]->track.lock);
+			spin_lock_init(&orders_8x60_all[i]->track.s_lock);
 		}
 
 		for (i = 0; i < ARRAY_SIZE(orders_8x60_modems); i++) {
-			mutex_init(&orders_8x60_modems[i]->powerup_lock);
-			mutex_init(&orders_8x60_modems[i]->shutdown_lock);
+			mutex_init(&orders_8x60_modems[i]->track.lock);
+			spin_lock_init(&orders_8x60_modems[i]->track.s_lock);
 		}
 
 		restart_orders = orders_8x60_all;
@@ -779,13 +799,12 @@
 	}
 
 	for (i = 0; i < n_restart_orders; i++) {
-		mutex_init(&restart_orders[i]->powerup_lock);
-		mutex_init(&restart_orders[i]->shutdown_lock);
+		mutex_init(&restart_orders[i]->track.lock);
+		spin_lock_init(&restart_orders[i]->track.s_lock);
 	}
 
-	if (restart_orders == NULL || n_restart_orders < 1) {
+	if (restart_orders == NULL || n_restart_orders < 1)
 		WARN_ON(1);
-	}
 
 	return 0;
 }
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index b535d53..a37260b 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -140,6 +140,7 @@
 	int ref_count;
 	struct mutex diagchar_mutex;
 	wait_queue_head_t wait_q;
+	wait_queue_head_t smd_wait_q;
 	struct diag_client_map *client_map;
 	int *data_ready;
 	int num_clients;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 9f7c7ac..c29a1d3f 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1412,6 +1412,7 @@
 		driver->mask_check = 0;
 		mutex_init(&driver->diagchar_mutex);
 		init_waitqueue_head(&driver->wait_q);
+		init_waitqueue_head(&driver->smd_wait_q);
 		INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn);
 		INIT_WORK(&(driver->diag_read_smd_work), diag_read_smd_work_fn);
 		INIT_WORK(&(driver->diag_read_smd_cntl_work),
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index e4501f4..d27ebcf 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -115,6 +115,7 @@
 			return APQ8064_TOOLS_ID;
 		case MSM_CPU_8930:
 		case MSM_CPU_8930AA:
+		case MSM_CPU_8930AB:
 			return MSM8930_TOOLS_ID;
 		case MSM_CPU_8974:
 			return MSM8974_TOOLS_ID;
@@ -142,6 +143,7 @@
 	case MSM_CPU_8064AB:
 	case MSM_CPU_8930:
 	case MSM_CPU_8930AA:
+	case MSM_CPU_8930AB:
 	case MSM_CPU_8627:
 	case MSM_CPU_9615:
 	case MSM_CPU_8974:
@@ -220,8 +222,9 @@
 
 void __diag_smd_send_req(void)
 {
-	void *buf = NULL;
-	int *in_busy_ptr = NULL;
+	void *buf = NULL, *temp_buf = NULL;
+	int total_recd = 0, r = 0, pkt_len, *in_busy_ptr = NULL;
+	int loop_count = 0;
 	struct diag_request *write_ptr_modem = NULL;
 
 	if (!driver->in_busy_1) {
@@ -235,27 +238,63 @@
 	}
 
 	if (driver->ch && buf) {
-		int r = smd_read_avail(driver->ch);
+		temp_buf = buf;
+		pkt_len = smd_cur_packet_size(driver->ch);
 
-		if (r > IN_BUF_SIZE) {
-			if (r < MAX_IN_BUF_SIZE) {
-				pr_err("diag: SMD sending in "
-						   "packets upto %d bytes", r);
-				buf = krealloc(buf, r, GFP_KERNEL);
-			} else {
-				pr_err("diag: SMD sending in "
-				"packets more than %d bytes", MAX_IN_BUF_SIZE);
+		while (pkt_len && (pkt_len != total_recd)) {
+			loop_count++;
+			r = smd_read_avail(driver->ch);
+			pr_debug("diag: In %s, received pkt %d %d\n",
+				__func__, r, total_recd);
+			if (!r) {
+				/* Nothing to read from SMD */
+				wait_event(driver->smd_wait_q,
+					((driver->ch == 0) ||
+					smd_read_avail(driver->ch)));
+				/* If the smd channel is open */
+				if (driver->ch) {
+					pr_debug("diag: In %s, return from wait_event\n",
+						__func__);
+					continue;
+				} else {
+					pr_debug("diag: In %s, return from wait_event ch closed\n",
+						__func__);
+					return;
+				}
+			}
+			total_recd += r;
+			if (total_recd > IN_BUF_SIZE) {
+				if (total_recd < MAX_IN_BUF_SIZE) {
+					pr_err("diag: In %s, SMD sending in packets up to %d bytes\n",
+						__func__, total_recd);
+					buf = krealloc(buf, total_recd,
+							GFP_KERNEL);
+				} else {
+					pr_err("diag: In %s, SMD sending in packets more than %d bytes\n",
+						__func__, MAX_IN_BUF_SIZE);
+					return;
+				}
+			}
+			if (pkt_len < r) {
+				pr_err("diag: In %s, SMD sending incorrect pkt\n",
+					__func__);
 				return;
 			}
+			if (pkt_len > r)
+				pr_debug("diag: In %s, SMD sending partial pkt %d %d %d %d\n",
+					__func__, pkt_len, r, total_recd,
+					loop_count);
+			/* keep reading for complete packet */
+			smd_read(driver->ch, temp_buf, r);
+			temp_buf += r;
 		}
-		if (r > 0) {
+
+		if (total_recd > 0) {
 			if (!buf)
-				pr_info("Out of diagmem for Modem\n");
+				pr_err("diag: Out of diagmem for Modem\n");
 			else {
-				APPEND_DEBUG('i');
-				smd_read(driver->ch, buf, r);
 				APPEND_DEBUG('j');
-				write_ptr_modem->length = r;
+				write_ptr_modem->length = total_recd;
 				*in_busy_ptr = 1;
 				diag_device_write(buf, MODEM_DATA,
 							 write_ptr_modem);
@@ -442,9 +481,10 @@
 
 void __diag_smd_wcnss_send_req(void)
 {
-	void *buf = NULL;
-	int *in_busy_wcnss_ptr = NULL;
+	void *buf = NULL, *temp_buf = NULL;
+	int total_recd = 0, r = 0, pkt_len, *in_busy_wcnss_ptr = NULL;
 	struct diag_request *write_ptr_wcnss = NULL;
+	int loop_count = 0;
 
 	if (!driver->in_busy_wcnss_1) {
 		buf = driver->buf_in_wcnss_1;
@@ -457,24 +497,64 @@
 	}
 
 	if (driver->ch_wcnss && buf) {
-		int r = smd_read_avail(driver->ch_wcnss);
-		if (r > IN_BUF_SIZE) {
-			if (r < MAX_IN_BUF_SIZE) {
-				pr_err("diag: wcnss packets > %d bytes", r);
-				buf = krealloc(buf, r, GFP_KERNEL);
-			} else {
-				pr_err("diag: wcnss pkt > %d", MAX_IN_BUF_SIZE);
+		temp_buf = buf;
+		pkt_len = smd_cur_packet_size(driver->ch_wcnss);
+
+		while (pkt_len && (pkt_len != total_recd)) {
+			loop_count++;
+			r = smd_read_avail(driver->ch_wcnss);
+			pr_debug("diag: In %s, received pkt %d %d\n",
+				__func__, r, total_recd);
+			if (!r) {
+				/* Nothing to read from SMD */
+				wait_event(driver->smd_wait_q,
+					((driver->ch_wcnss == 0) ||
+					smd_read_avail(driver->ch_wcnss)));
+				/* If the smd channel is open */
+				if (driver->ch_wcnss) {
+					pr_debug("diag: In %s, return from wait_event\n",
+						__func__);
+					continue;
+				} else {
+					pr_debug("diag: In %s, return from wait_event ch_wcnss closed\n",
+						__func__);
+					return;
+				}
+			}
+			total_recd += r;
+			if (total_recd > IN_BUF_SIZE) {
+				if (total_recd < MAX_IN_BUF_SIZE) {
+					pr_err("diag: In %s, SMD sending in packets up to %d bytes\n",
+						__func__, total_recd);
+					buf = krealloc(buf, total_recd,
+								 GFP_KERNEL);
+				} else {
+					pr_err("diag: In %s, SMD sending in packets more than %d bytes\n",
+						__func__, MAX_IN_BUF_SIZE);
+					return;
+				}
+			}
+			if (pkt_len < r) {
+				pr_err("diag: In %s, SMD sending incorrect pkt\n",
+					__func__);
 				return;
 			}
+			if (pkt_len > r) {
+				pr_debug("diag: In %s, SMD sending partial pkt %d %d %d %d\n",
+					__func__, pkt_len, r, total_recd,
+					loop_count);
+			}
+			/* keep reading for complete packet */
+			smd_read(driver->ch_wcnss, temp_buf, r);
+			temp_buf += r;
 		}
-		if (r > 0) {
+
+		if (total_recd > 0) {
 			if (!buf) {
-				pr_err("Out of diagmem for wcnss\n");
+				pr_err("diag: Out of diagmem for wcnss\n");
 			} else {
-				APPEND_DEBUG('i');
-				smd_read(driver->ch_wcnss, buf, r);
 				APPEND_DEBUG('j');
-				write_ptr_wcnss->length = r;
+				write_ptr_wcnss->length = total_recd;
 				*in_busy_wcnss_ptr = 1;
 				diag_device_write(buf, WCNSS_DATA,
 					 write_ptr_wcnss);
@@ -488,9 +568,10 @@
 
 void __diag_smd_lpass_send_req(void)
 {
-	void *buf = NULL;
-	int *in_busy_lpass_ptr = NULL;
+	void *buf = NULL, *temp_buf = NULL;
+	int total_recd = 0, r = 0, pkt_len, *in_busy_lpass_ptr = NULL;
 	struct diag_request *write_ptr_lpass = NULL;
+	int loop_count = 0;
 
 	if (!driver->in_busy_lpass_1) {
 		buf = driver->buf_in_lpass_1;
@@ -503,27 +584,63 @@
 	}
 
 	if (driver->chlpass && buf) {
-		int r = smd_read_avail(driver->chlpass);
+		temp_buf = buf;
+		pkt_len = smd_cur_packet_size(driver->chlpass);
 
-		if (r > IN_BUF_SIZE) {
-			if (r < MAX_IN_BUF_SIZE) {
-				pr_err("diag: SMD sending in "
-						   "packets upto %d bytes", r);
-				buf = krealloc(buf, r, GFP_KERNEL);
-			} else {
-				pr_err("diag: SMD sending in "
-				"packets more than %d bytes", MAX_IN_BUF_SIZE);
+		while (pkt_len && (pkt_len != total_recd)) {
+			loop_count++;
+			r = smd_read_avail(driver->chlpass);
+			pr_debug("diag: In %s, received pkt %d %d\n",
+				__func__, r, total_recd);
+			if (!r) {
+				/* Nothing to read from SMD */
+				wait_event(driver->smd_wait_q,
+					((driver->chlpass == 0) ||
+					smd_read_avail(driver->chlpass)));
+				/* If the smd channel is open */
+				if (driver->chlpass) {
+					pr_debug("diag: In %s, return from wait_event\n",
+						__func__);
+					continue;
+				} else {
+					pr_debug("diag: In %s, return from wait_event chlpass closed\n",
+						__func__);
+					return;
+				}
+			}
+			total_recd += r;
+			if (total_recd > IN_BUF_SIZE) {
+				if (total_recd < MAX_IN_BUF_SIZE) {
+					pr_err("diag: In %s, SMD sending in packets up to %d bytes\n",
+						__func__, total_recd);
+					buf = krealloc(buf, total_recd,
+								 GFP_KERNEL);
+				} else {
+					pr_err("diag: In %s, SMD sending in packets more than %d bytes\n",
+						__func__, MAX_IN_BUF_SIZE);
+					return;
+				}
+			}
+			if (pkt_len < r) {
+				pr_err("diag: In %s, SMD sending incorrect pkt\n",
+					__func__);
 				return;
 			}
+			if (pkt_len > r)
+				pr_debug("diag: In %s, SMD sending partial pkt %d %d %d %d\n",
+					__func__, pkt_len, r, total_recd,
+					loop_count);
+			/* keep reading for complete packet */
+			smd_read(driver->chlpass, temp_buf, r);
+			temp_buf += r;
 		}
-		if (r > 0) {
+
+		if (total_recd > 0) {
 			if (!buf)
-				printk(KERN_INFO "Out of diagmem for LPASS\n");
+				pr_err("diag: Out of diagmem for LPASS\n");
 			else {
-				APPEND_DEBUG('i');
-				smd_read(driver->chlpass, buf, r);
 				APPEND_DEBUG('j');
-				write_ptr_lpass->length = r;
+				write_ptr_lpass->length = total_recd;
 				*in_busy_lpass_ptr = 1;
 				diag_device_write(buf, LPASS_DATA,
 							 write_ptr_lpass);
@@ -1222,14 +1339,16 @@
 static void diag_smd_notify(void *ctxt, unsigned event)
 {
 	if (event == SMD_EVENT_CLOSE) {
+		driver->ch = 0;
+		wake_up(&driver->smd_wait_q);
 		queue_work(driver->diag_cntl_wq,
 			 &(driver->diag_clean_modem_reg_work));
-		driver->ch = 0;
 		return;
 	} else if (event == SMD_EVENT_OPEN) {
 		if (ch_temp)
 			driver->ch = ch_temp;
 	}
+	wake_up(&driver->smd_wait_q);
 	queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
 }
 
@@ -1237,14 +1356,16 @@
 static void diag_smd_lpass_notify(void *ctxt, unsigned event)
 {
 	if (event == SMD_EVENT_CLOSE) {
+		driver->chlpass = 0;
+		wake_up(&driver->smd_wait_q);
 		queue_work(driver->diag_cntl_wq,
 			 &(driver->diag_clean_lpass_reg_work));
-		driver->chlpass = 0;
 		return;
 	} else if (event == SMD_EVENT_OPEN) {
 		if (chlpass_temp)
 			driver->chlpass = chlpass_temp;
 	}
+	wake_up(&driver->smd_wait_q);
 	queue_work(driver->diag_wq, &(driver->diag_read_smd_lpass_work));
 }
 #endif
@@ -1252,14 +1373,16 @@
 static void diag_smd_wcnss_notify(void *ctxt, unsigned event)
 {
 	if (event == SMD_EVENT_CLOSE) {
+		driver->ch_wcnss = 0;
+		wake_up(&driver->smd_wait_q);
 		queue_work(driver->diag_cntl_wq,
 			 &(driver->diag_clean_wcnss_reg_work));
-		driver->ch_wcnss = 0;
 		return;
 	} else if (event == SMD_EVENT_OPEN) {
 		if (ch_wcnss_temp)
 			driver->ch_wcnss = ch_wcnss_temp;
 	}
+	wake_up(&driver->smd_wait_q);
 	queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work));
 }
 
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index bd8c4a4..4628ba7 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -846,7 +846,6 @@
 {
 	struct vdec_picsize pic_res;
 	int rc;
-	struct video_buffer_req vdec_buf_req;
 
 	pic_res.frame_height = 1080;
 	pic_res.frame_width  = 1920;
@@ -864,15 +863,6 @@
 		DBG("Failed in mpq_int_vid_dec_set_cont_on_reconfig : %d\n",\
 			rc);
 
-	rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
-	if (rc)
-		DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
-
-	vdec_buf_req.num_output_buffers = 12;
-	rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_buf_req);
-	if (rc)
-		DBG("Failed in mpq_int_set_out_buffer_req (15) : %d\n", rc);
-
 	return rc;
 
 }
@@ -1285,6 +1275,27 @@
 	return 0;
 }
 
+static int mpq_int_vid_dec_set_buffer_req(struct video_client_ctx *client_ctx,
+				  struct video_buffer_req vdec_buf_req)
+{
+	int rc = 0;
+	struct video_buffer_req vdec_req;
+
+	rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_req);
+	if (rc)
+		DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
+
+	vdec_req.num_output_buffers = vdec_buf_req.num_output_buffers;
+	DBG(" num_output_buffers Set to %u\n", vdec_buf_req.num_output_buffers);
+	if (!vdec_buf_req.num_output_buffers)
+		return -EINVAL;
+	rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_req);
+	if (rc)
+		DBG("Failed in mpq_int_set_out_buffer_req  %d\n", rc);
+
+	return 0;
+}
+
 static int mpq_int_vid_dec_set_buffer(struct mpq_dvb_video_inst *dev_inst,
 			      struct video_data_buffer *data_buffer,
 			      enum buffer_dir dir_buffer)
@@ -2006,6 +2017,10 @@
 		DBG("cmd : VIDEO_CMD_GET_BUFFER_REQ\n");
 		rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &cmd->buf_req);
 		break;
+	case VIDEO_CMD_SET_BUFFER_COUNT:
+		DBG("cmd : VIDEO_CMD_SET_BUFFER_COUNT\n");
+		rc = mpq_int_vid_dec_set_buffer_req(client_ctx, cmd->buf_req);
+		break;
 	case VIDEO_CMD_READ_RAW_OUTPUT:
 		DBG("cmd : VIDEO_CMD_READ_RAW_OUTPUT\n");
 		rc = mpq_int_vid_dec_fill_output_buffer(client_ctx,
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index b91f3d1..3aa38d2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1502,48 +1502,6 @@
 	mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
-	struct mmc_card *card;
-	unsigned int timeout;
-	unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-	int err = 0;
-
-	card = host->card;
-	mmc_claim_host(host);
-
-	/*
-	 * Send power notify command only if card
-	 * is mmc and notify state is powered ON
-	 */
-	if (card && mmc_card_mmc(card) &&
-	    (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
-		if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
-			notify_type = EXT_CSD_POWER_OFF_SHORT;
-			timeout = card->ext_csd.generic_cmd6_time;
-			card->poweroff_notify_state = MMC_POWEROFF_SHORT;
-		} else {
-			notify_type = EXT_CSD_POWER_OFF_LONG;
-			timeout = card->ext_csd.power_off_longtime;
-			card->poweroff_notify_state = MMC_POWEROFF_LONG;
-		}
-
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				 EXT_CSD_POWER_OFF_NOTIFICATION,
-				 notify_type, timeout);
-
-		if (err && err != -EBADMSG)
-			pr_err("Device failed to respond within %d poweroff time.",
-				   timeout);
-			pr_err("Forcefully powering down the device\n");
-
-		/* Set the card state to no notification after the poweroff */
-		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
-	}
-	 mmc_release_host(host);
-}
-
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -1601,30 +1559,11 @@
 
 void mmc_power_off(struct mmc_host *host)
 {
-	int err = 0;
 	mmc_host_clk_hold(host);
 
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
 
-	mmc_poweroff_notify(host);
-	/*
-	 * For eMMC 4.5 device send AWAKE command before
-	 * POWER_OFF_NOTIFY command, because in sleep state
-	 * eMMC 4.5 devices respond to only RESET and AWAKE cmd
-	 */
-	if (host->card && mmc_card_is_sleep(host->card) &&
-	    host->bus_ops->resume) {
-		err = host->bus_ops->resume(host);
-
-		if (!err)
-			mmc_poweroff_notify(host);
-		else
-			pr_warning("%s: error %d during resume",
-					   mmc_hostname(host), err);
-			pr_warning(" (continue with poweroff sequence)\n");
-	}
-
 	/*
 	 * Reset ocr mask to be the highest possible voltage supported for
 	 * this mmc host. This value will be used at next power up.
@@ -2888,7 +2827,6 @@
 			break;
 		}
 		host->rescan_disable = 1;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
 		spin_unlock_irqrestore(&host->lock, flags);
 		if (cancel_delayed_work_sync(&host->detect))
 			wake_unlock(&host->detect_wake_lock);
@@ -2917,7 +2855,6 @@
 			break;
 		}
 		host->rescan_disable = 0;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
 		spin_unlock_irqrestore(&host->lock, flags);
 		mmc_detect_change(host, 0);
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 50af7fa..47fd9b9 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1028,7 +1028,7 @@
 		 * so check for success and update the flag
 		 */
 		if (!err)
-			card->poweroff_notify_state = MMC_POWERED_ON;
+			card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
 	}
 
 	/*
@@ -1356,6 +1356,35 @@
 	return err;
 }
 
+static int mmc_can_poweroff_notify(const struct mmc_card *card)
+{
+	return card &&
+		mmc_card_mmc(card) &&
+		(card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
+}
+
+static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
+{
+	unsigned int timeout = card->ext_csd.generic_cmd6_time;
+	int err;
+
+	/* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
+	if (notify_type == EXT_CSD_POWER_OFF_LONG)
+		timeout = card->ext_csd.power_off_longtime;
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			 EXT_CSD_POWER_OFF_NOTIFICATION,
+			 notify_type, timeout);
+	if (err)
+		pr_err("%s: Power Off Notification timed out, %u\n",
+		       mmc_hostname(card->host), timeout);
+
+	/* Disable the power off notification after the switch operation. */
+	card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
+
+	return err;
+}
+
 /*
  * Host is being removed. Free up the current card.
  */
@@ -1419,11 +1448,11 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_can_sleep(host)) {
+	if (mmc_can_poweroff_notify(host->card))
+		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
+	else if (mmc_card_can_sleep(host))
 		err = mmc_card_sleep(host);
-		if (!err)
-			mmc_card_set_sleep(host->card);
-	} else if (!mmc_host_is_spi(host))
+	else if (!mmc_host_is_spi(host))
 		mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 	mmc_release_host(host);
@@ -1456,7 +1485,6 @@
 	int ret;
 
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_card_clr_sleep(host->card);
 	mmc_claim_host(host);
 	ret = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index ab3fc46..bd374f6 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1790,11 +1790,6 @@
 	if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	if (host->pdata->blk_settings) {
 		mmc->max_segs = host->pdata->blk_settings->max_segs;
 		mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 29413ab..2fbd804 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5841,6 +5841,7 @@
 	mmc->caps2 |= MMC_CAP2_SANITIZE;
 	mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
 	mmc->caps2 |= MMC_CAP2_INIT_BKOPS;
+	mmc->caps2 |= MMC_CAP2_POWEROFF_NOTIFY;
 
 	if (plat->nonremovable)
 		mmc->caps |= MMC_CAP_NONREMOVABLE;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2f7a2f3..43f7e77 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2581,15 +2581,6 @@
 	if (caps[1] & SDHCI_DRIVER_TYPE_D)
 		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
 
-	/*
-	 * If Power Off Notify capability is enabled by the host,
-	 * set notify to short power off notify timeout value.
-	 */
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	/* Initial value for re-tuning timer count */
 	host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
 			      SDHCI_RETUNING_TIMER_COUNT_SHIFT;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 8d5244b..ef555f7 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -1145,6 +1145,10 @@
 		goto fail_chg_enable;
 	}
 
+	/* Get the charging-disabled property */
+	charging_disabled = of_property_read_bool(spmi->dev.of_node,
+					"qcom,chg-charging-disabled");
+
 	spmi_for_each_container_dev(spmi_resource, spmi) {
 		if (!spmi_resource) {
 			pr_err("qpnp_chg: spmi resource absent\n");
@@ -1278,6 +1282,8 @@
 
 	qpnp_chg_charge_en(chip, 1);
 	the_chip = chip;
+	qpnp_chg_charge_dis(chip, charging_disabled);
+
 	pr_info("Probe success !\n");
 	return 0;
 
@@ -1293,7 +1299,6 @@
 qpnp_charger_remove(struct spmi_device *spmi)
 {
 	struct qpnp_chg_chip *chip = dev_get_drvdata(&spmi->dev);
-
 	dev_set_drvdata(&spmi->dev, NULL);
 	kfree(chip);
 
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index e2f37cc..58a1d66 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1257,7 +1257,7 @@
 	else
 		clk_prepare_enable(dev->hclk);
 
-	ret = msm_slim_sps_init(dev, bam_mem, MGR_STATUS);
+	ret = msm_slim_sps_init(dev, bam_mem, MGR_STATUS, false);
 	if (ret != 0) {
 		dev_err(dev->dev, "error SPS init\n");
 		goto err_sps_init_failed;
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 8a1ea84..7cd34d3 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -494,7 +494,7 @@
 
 /* Registers BAM h/w resource with SPS driver and initializes msgq endpoints */
 int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
-			u32 pipe_reg)
+			u32 pipe_reg, bool remote)
 {
 	int i, ret;
 	u32 bam_handle;
@@ -521,10 +521,16 @@
 	bam_props.virt_addr = dev->bam.base;
 	bam_props.phys_addr = bam_mem->start;
 	bam_props.irq = dev->bam.irq;
-	bam_props.manage = SPS_BAM_MGR_LOCAL;
+	if (!remote) {
+		bam_props.manage = SPS_BAM_MGR_LOCAL;
+		bam_props.sec_config = SPS_BAM_SEC_DO_CONFIG;
+	} else {
+		bam_props.manage = SPS_BAM_MGR_DEVICE_REMOTE |
+					SPS_BAM_MGR_MULTI_EE;
+		bam_props.sec_config = SPS_BAM_SEC_DO_NOT_CONFIG;
+	}
 	bam_props.summing_threshold = MSM_SLIM_PERF_SUMM_THRESHOLD;
 
-	bam_props.sec_config = SPS_BAM_SEC_DO_CONFIG;
 	bam_props.p_sec_config_props = &sec_props;
 
 	bam_props.options = SPS_O_DESC_DONE | SPS_O_ERROR |
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index f68475a..35bb040 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -246,6 +246,6 @@
 u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len);
 int msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset);
 int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
-			u32 pipe_reg);
+			u32 pipe_reg, bool remote);
 void msm_slim_sps_exit(struct msm_slim_ctrl *dev);
 #endif
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index d7da073..bf5410a 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -1016,11 +1016,13 @@
 
 		dwc->ep0state = EP0_STATUS_PHASE;
 
-		if (dwc->delayed_status) {
+		if (dwc->delayed_status &&
+				list_empty(&dwc->eps[0]->request_list)) {
 			WARN_ON_ONCE(event->endpoint_number != 1);
 			dev_vdbg(dwc->dev, "Mass Storage delayed status\n");
 			return;
 		}
+		dwc->delayed_status = false;
 
 		dwc3_ep0_do_control_status(dwc, event);
 	}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 35f7283..ab44d1e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2500,7 +2500,7 @@
 	dev_set_name(&dwc->gadget.dev, "gadget");
 
 	dwc->gadget.ops			= &dwc3_gadget_ops;
-	dwc->gadget.max_speed		= USB_SPEED_SUPER;
+	dwc->gadget.max_speed		= USB_SPEED_HIGH;
 	dwc->gadget.speed		= USB_SPEED_UNKNOWN;
 	dwc->gadget.dev.parent		= dwc->dev;
 	dwc->gadget.sg_supported	= true;
diff --git a/drivers/usb/gadget/f_qdss.c b/drivers/usb/gadget/f_qdss.c
index 4f098f1..fd4f352 100644
--- a/drivers/usb/gadget/f_qdss.c
+++ b/drivers/usb/gadget/f_qdss.c
@@ -436,11 +436,30 @@
 	}
 }
 
+static void usb_qdss_disconnect_work(struct work_struct *work)
+{
+	struct f_qdss *qdss = container_of(work, struct f_qdss, disconnect_w);
+	int status;
+
+	pr_debug("usb_qdss_disconnect_work\n");
+
+	/* notify qdss to cancell all active transfers*/
+	if (qdss->ch.notify) {
+		qdss->ch.notify(qdss->ch.priv, USB_QDSS_DISCONNECT, NULL,
+			NULL);
+		/* If the app was never started, we can skip USB BAM reset */
+		status = set_qdss_data_connection(qdss->data,
+			qdss->data->address, 0);
+		if (status)
+			pr_err("qdss_disconnect error");
+	}
+
+}
+
 static void qdss_disable(struct usb_function *f)
 {
 	struct f_qdss	*qdss = func_to_qdss(f);
 	unsigned long flags;
-	int status;
 
 	pr_debug("qdss_disable\n");
 
@@ -451,24 +470,15 @@
 	/*cancell all active xfers*/
 	qdss_eps_disable(f);
 
-	/* notify qdss to cancell all active transfers*/
-	if (qdss->ch.notify) {
-		qdss->ch.notify(qdss->ch.priv, USB_QDSS_DISCONNECT, NULL,
-			NULL);
-		/* If the app was never started, we can skip USB BAM reset */
-		status = set_qdss_data_connection(qdss->data,
-			qdss->data->address, 0);
-		if (status)
-			pr_err("qdss_disable error");
-	}
+	schedule_work(&qdss->disconnect_w);
 }
 
-static void usb_qdss_work_func(struct work_struct *work)
+static void usb_qdss_connect_work(struct work_struct *work)
 {
-	struct f_qdss *qdss = container_of(work, struct f_qdss, qdss_work);
+	struct f_qdss *qdss = container_of(work, struct f_qdss, connect_w);
 	int status;
 
-	pr_debug("usb_qdss_work_func\n");
+	pr_debug("usb_qdss_connect_work\n");
 
 	status = init_data(qdss->data);
 	if (status) {
@@ -549,7 +559,7 @@
 		qdss->usb_connected = 1;
 
 	if (qdss->usb_connected && ch->app_conn)
-		schedule_work(&qdss->qdss_work);
+		schedule_work(&qdss->connect_w);
 
 	return 0;
 fail:
@@ -618,7 +628,8 @@
 	spin_lock_init(&qdss->lock);
 	INIT_LIST_HEAD(&qdss->ctrl_read_pool);
 	INIT_LIST_HEAD(&qdss->ctrl_write_pool);
-	INIT_WORK(&qdss->qdss_work, usb_qdss_work_func);
+	INIT_WORK(&qdss->connect_w, usb_qdss_connect_work);
+	INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work);
 
 	status = usb_add_function(c, &qdss->function);
 	if (status) {
@@ -767,7 +778,7 @@
 
 	/* the case USB cabel was connected befor qdss called  qdss_open*/
 	if (qdss->usb_connected == 1)
-		schedule_work(&qdss->qdss_work);
+		schedule_work(&qdss->connect_w);
 
 	return ch;
 }
diff --git a/drivers/usb/gadget/f_qdss.h b/drivers/usb/gadget/f_qdss.h
index b61244b..d6be8b7 100644
--- a/drivers/usb/gadget/f_qdss.h
+++ b/drivers/usb/gadget/f_qdss.h
@@ -32,7 +32,8 @@
 	struct usb_qdss_ch ch;
 	struct list_head ctrl_read_pool;
 	struct list_head ctrl_write_pool;
-	struct work_struct qdss_work;
+	struct work_struct connect_w;
+	struct work_struct disconnect_w;
 	spinlock_t lock;
 	unsigned int data_enabled:1;
 	unsigned int ctrl_in_enabled:1;
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index c78fd0c..e821fda 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -21,7 +21,7 @@
 #include <linux/ratelimit.h>
 #include <mach/usb_bridge.h>
 
-#define MAX_RX_URBS			50
+#define MAX_RX_URBS			100
 #define RMNET_RX_BUFSIZE		2048
 
 #define STOP_SUBMIT_URB_LIMIT		500
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index ca1b155..36a91f1 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -536,6 +536,9 @@
 				test_bit(ID_B, &dev->inputs))
 		charge = USB_IDCHG_MAX;
 
+	if (dev->curr_power == charge)
+		return 0;
+
 	pr_debug("Charging with %dmA current\n", charge);
 	/* Call vbus_draw only if the charger is of known type and also
 	 * ignore request to stop charging as a result of suspend interrupt
@@ -545,6 +548,8 @@
 		(charge || new_chg != USB_CHG_TYPE__WALLCHARGER))
 			pdata->chg_vbus_draw(charge);
 
+	dev->curr_power = charge;
+
 	if (new_chg == USB_CHG_TYPE__WALLCHARGER) {
 		wake_lock(&dev->wlock);
 		queue_work(dev->wq, &dev->sm_work);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 18f8729..a4c7131 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1120,14 +1120,12 @@
 
 static void msm_otg_notify_host_mode(struct msm_otg *motg, bool host_mode)
 {
-	struct power_supply *usb = psy ? psy : &motg->usb_psy;
-
-	if (!usb) {
+	if (!psy) {
 		pr_err("No USB power supply registered!\n");
 		return;
 	}
 
-	if (psy) {
+	if (legacy_power_supply) {
 		/* legacy support */
 		if (host_mode)
 			power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_SYSTEM);
@@ -1136,14 +1134,13 @@
 		return;
 	} else {
 		motg->host_mode = host_mode;
-		power_supply_changed(usb);
+		power_supply_changed(psy);
 	}
 }
 
 static int msm_otg_notify_chg_type(struct msm_otg *motg)
 {
 	static int charger_type;
-	struct power_supply *usb = psy ? psy : &motg->usb_psy;
 
 	/*
 	 * TODO
@@ -1167,40 +1164,38 @@
 	else
 		charger_type = POWER_SUPPLY_TYPE_BATTERY;
 
-	if (!usb) {
+	if (!psy) {
 		pr_err("No USB power supply registered!\n");
 		return -EINVAL;
 	}
 
 	pr_debug("setting usb power supply type %d\n", charger_type);
-	power_supply_set_supply_type(usb, charger_type);
+	power_supply_set_supply_type(psy, charger_type);
 	return 0;
 }
 
 static int msm_otg_notify_power_supply(struct msm_otg *motg, unsigned mA)
 {
-	struct power_supply *usb = psy ? psy : &motg->usb_psy;
-
-	if (!usb) {
+	if (!psy) {
 		dev_dbg(motg->phy.dev, "no usb power supply registered\n");
 		goto psy_error;
 	}
 
 	if (motg->cur_power == 0 && mA > 2) {
 		/* Enable charging */
-		if (power_supply_set_online(usb, true))
+		if (power_supply_set_online(psy, true))
 			goto psy_error;
-		if (power_supply_set_current_limit(usb, 1000*mA))
+		if (power_supply_set_current_limit(psy, 1000*mA))
 			goto psy_error;
 	} else if (motg->cur_power > 0 && (mA == 0 || mA == 2)) {
 		/* Disable charging */
-		if (power_supply_set_online(usb, false))
+		if (power_supply_set_online(psy, false))
 			goto psy_error;
 		/* Set max current limit */
-		if (power_supply_set_current_limit(usb, 0))
+		if (power_supply_set_current_limit(psy, 0))
 			goto psy_error;
 	}
-	power_supply_changed(usb);
+	power_supply_changed(psy);
 	return 0;
 
 psy_error:
@@ -3386,8 +3381,7 @@
 				  enum power_supply_property psp,
 				  union power_supply_propval *val)
 {
-	struct msm_otg *motg = container_of(psy, struct msm_otg,
-								usb_psy);
+	struct msm_otg *motg = container_of(psy, struct msm_otg, usb_psy);
 	switch (psp) {
 	case POWER_SUPPLY_PROP_SCOPE:
 		if (motg->host_mode)
@@ -3413,8 +3407,7 @@
 				  enum power_supply_property psp,
 				  const union power_supply_propval *val)
 {
-	struct msm_otg *motg = container_of(psy, struct msm_otg,
-								usb_psy);
+	struct msm_otg *motg = container_of(psy, struct msm_otg, usb_psy);
 
 	switch (psp) {
 	/* Process PMIC notification in PRESENT prop */
@@ -4011,19 +4004,19 @@
 	motg->usb_psy.get_property = otg_power_get_property_usb;
 	motg->usb_psy.set_property = otg_power_set_property_usb;
 
-	if (motg->pdata->otg_control == OTG_PMIC_CONTROL) {
+	if (!pm8921_charger_register_vbus_sn(NULL)) {
 		/* if pm8921 use legacy implementation */
-		if (!pm8921_charger_register_vbus_sn(&msm_otg_set_vbus_state)) {
-			dev_dbg(motg->phy.dev, "%s: legacy support\n",
-				__func__);
-			legacy_power_supply = true;
-		} else {
-			ret = msm_otg_register_power_supply(pdev, motg);
-			if (ret)
-				goto remove_phy;
-		}
+		dev_dbg(motg->phy.dev, "%s: legacy support\n", __func__);
+		legacy_power_supply = true;
+	} else {
+		/* otherwise register our own power supply */
+		if (!msm_otg_register_power_supply(pdev, motg))
+			psy = &motg->usb_psy;
 	}
 
+	if (legacy_power_supply && pdata->otg_control == OTG_PMIC_CONTROL)
+		pm8921_charger_register_vbus_sn(&msm_otg_set_vbus_state);
+
 	return 0;
 
 remove_phy:
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index d21a095..73b8c60 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -396,7 +396,6 @@
 
 	ctl->width = width;
 	ctl->height = height;
-	ctl->dst_format = mfd->panel_info.out_format;
 
 	if (!ctl->mixer_left) {
 		ctl->mixer_left =
@@ -467,6 +466,20 @@
 
 	ctl->opmode |= (ctl->intf_num << 4);
 
+	if (ctl->intf_num == MDSS_MDP_NO_INTF) {
+		ctl->dst_format = mfd->panel_info.out_format;
+	} else {
+		switch (mfd->panel_info.bpp) {
+		case 18:
+			ctl->dst_format = MDSS_MDP_PANEL_FORMAT_RGB666;
+			break;
+		case 24:
+		default:
+			ctl->dst_format = MDSS_MDP_PANEL_FORMAT_RGB888;
+			break;
+		}
+	}
+
 	if (ctl->mixer_right) {
 		ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
 			       MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT;
@@ -560,6 +573,12 @@
 	temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8));
 	MDSS_MDP_REG_WRITE(MDSS_MDP_REG_DISP_INTF_SEL, temp);
 
+	if (ctl->intf_num != MDSS_MDP_NO_INTF) {
+		off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
+		MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_PANEL_FORMAT,
+				   ctl->dst_format);
+	}
+
 	outsize = (mixer->height << 16) | mixer->width;
 	off = MDSS_MDP_REG_LM_OFFSET(mixer->num);
 	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, outsize);
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 651d595..1da30b8 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -395,6 +395,7 @@
 #define MDSS_MDP_REG_INTF_FRAME_COUNT			0x0AC
 #define MDSS_MDP_REG_INTF_LINE_COUNT			0x0B0
 #define MDSS_MDP_PANEL_FORMAT_RGB888			0x213F
+#define MDSS_MDP_PANEL_FORMAT_RGB666			0x212A
 
 enum mdss_mdp_pingpong_index {
 	MDSS_MDP_PINGPONG0,
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 3c7c362..4d3fbf0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -153,8 +153,6 @@
 			   p->hsync_skew);
 	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_POLARITY_CTL,
 			   polarity_ctl);
-	MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_PANEL_FORMAT,
-			   MDSS_MDP_PANEL_FORMAT_RGB888);
 
 	return 0;
 }
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h
index 81475c2..2a2a53d 100644
--- a/include/linux/dvb/video.h
+++ b/include/linux/dvb/video.h
@@ -113,6 +113,7 @@
 #define VIDEO_CMD_FREE_H264_MV_BUFFER (17)
 #define VIDEO_CMD_CLEAR_INPUT_BUFFER  (18)
 #define VIDEO_CMD_CLEAR_OUTPUT_BUFFER (19)
+#define VIDEO_CMD_SET_BUFFER_COUNT    (20)
 
 /* Flags for VIDEO_CMD_FREEZE */
 #define VIDEO_CMD_FREEZE_TO_BLACK	(1 << 0)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 30ca87c..fb854ba 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -60,6 +60,7 @@
 	unsigned int		sa_timeout;		/* Units: 100ns */
 	unsigned int		generic_cmd6_time;	/* Units: 10ms */
 	unsigned int            power_off_longtime;     /* Units: ms */
+	u8			power_off_notification;	/* state */
 	unsigned int		hs_max_dtr;
 #define MMC_HIGH_26_MAX_DTR	26000000
 #define MMC_HIGH_52_MAX_DTR	52000000
@@ -309,7 +310,6 @@
 #define MMC_CARD_SDXC		(1<<6)		/* card is SDXC */
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
-#define MMC_STATE_SLEEP		(1<<9)		/* card is in sleep state */
 #define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
@@ -326,11 +326,6 @@
 #define MMC_QUIRK_LONG_READ_TIME (1<<9)		/* Data read time > CSD says */
 						/* byte mode */
 #define MMC_QUIRK_INAND_DATA_TIMEOUT  (1<<8)    /* For incorrect data timeout */
-	unsigned int    poweroff_notify_state;	/* eMMC4.5 notify feature */
-#define MMC_NO_POWER_NOTIFICATION	0
-#define MMC_POWERED_ON			1
-#define MMC_POWEROFF_SHORT		2
-#define MMC_POWEROFF_LONG		3
 
 	unsigned int		erase_size;	/* erase size in sectors */
  	unsigned int		erase_shift;	/* if erase unit is power 2 */
@@ -486,7 +481,6 @@
 #define mmc_sd_card_uhs(c)	((c)->state & MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
-#define mmc_card_is_sleep(c)	((c)->state & MMC_STATE_SLEEP)
 #define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
@@ -499,11 +493,9 @@
 #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
-#define mmc_card_set_sleep(c)	((c)->state |= MMC_STATE_SLEEP)
 #define mmc_card_set_doing_bkops(c)	((c)->state |= MMC_STATE_DOING_BKOPS)
-
 #define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
-#define mmc_card_clr_sleep(c)	((c)->state &= ~MMC_STATE_SLEEP)
+
 /*
  * Quirk add/remove for MMC products.
  */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 8f0a756..f435221 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -251,10 +251,6 @@
 #define MMC_CAP2_SANITIZE	(1 << 13)		/* Support Sanitize */
 #define MMC_CAP2_INIT_BKOPS	    (1 << 15)	/* Need to set BKOPS_EN */
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
-	unsigned int        power_notify_type;
-#define MMC_HOST_PW_NOTIFY_NONE		0
-#define MMC_HOST_PW_NOTIFY_SHORT	1
-#define MMC_HOST_PW_NOTIFY_LONG		2
 
 	int			clk_requests;	/* internal reference counter */
 	unsigned int		clk_delay;	/* number of MCI clk hold cycles */
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 1f6dbf1..4e41c80 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -42,6 +42,12 @@
 /* CVS CAL Size: 49152 = 48 * 1024 */
 #define CVS_CAL_SIZE 49152
 
+enum {
+	VOC_TOKEN_NONE,
+	VOIP_MEM_MAP_TOKEN,
+	VOC_CAL_MEM_MAP_TOKEN,
+};
+
 static struct common_data common;
 
 static int voice_send_enable_vocproc_cmd(struct voice_data *v);
@@ -50,7 +56,6 @@
 static int voice_send_set_device_cmd(struct voice_data *v);
 static int voice_send_disable_vocproc_cmd(struct voice_data *v);
 static int voice_send_vol_index_cmd(struct voice_data *v);
-static int voice_send_mvm_map_memory_physical_cmd(struct voice_data *v);
 static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v,
 						    unsigned int bufcnt);
 static int voice_send_mvm_cal_network_cmd(struct voice_data *v);
@@ -59,6 +64,16 @@
 static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v);
 static int voice_set_packet_exchange_mode_and_config(uint16_t session_id,
 						     uint32_t mode);
+
+static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
+static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v);
+static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v);
+static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v);
+
 static int voice_cvs_stop_playback(struct voice_data *v);
 static int voice_cvs_start_playback(struct voice_data *v);
 static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
@@ -1263,32 +1278,557 @@
 	return -EINVAL;
 }
 
-static int voice_send_mvm_map_memory_physical_cmd(struct voice_data *v)
+static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
+{
+	struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvs_reg_cal_cmd, 0, sizeof(cvs_reg_cal_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvs) {
+		pr_err("%s: apr_cvs is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.cal_mem_handle) {
+		pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	get_all_vocstrm_cal(&cal_block);
+	if (cal_block.cal_size == 0) {
+		pr_err("%s: CVS cal size is 0\n", __func__);
+
+		goto fail;
+	}
+
+	cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
+	cvs_reg_cal_cmd.hdr.src_port = v->session_id;
+	cvs_reg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
+	cvs_reg_cal_cmd.hdr.token = 0;
+	cvs_reg_cal_cmd.hdr.opcode =
+				VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2;
+
+	cvs_reg_cal_cmd.cvs_cal_data.cal_mem_handle = common.cal_mem_handle;
+	cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address = cal_block.cal_paddr;
+	cvs_reg_cal_cmd.cvs_cal_data.cal_mem_size = cal_block.cal_size;
+
+	/* Get the column info corresponding to CVS cal from ACDB. */
+	get_voice_col_data(VOCSTRM_CAL, &cal_block);
+	memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0],
+	       (void *) cal_block.cal_kvaddr,
+	       cal_block.cal_size);
+
+	v->cvs_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_reg_cal_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d registering CVS cal\n", __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvs_wait,
+				 (v->cvs_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
+{
+	struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvs_dereg_cal_cmd, 0, sizeof(cvs_dereg_cal_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvs) {
+		pr_err("%s: apr_cvs is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	get_all_vocstrm_cal(&cal_block);
+	if (cal_block.cal_size == 0)
+		return 0;
+
+	cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
+	cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
+	cvs_dereg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
+	cvs_dereg_cal_cmd.hdr.token = 0;
+	cvs_dereg_cal_cmd.hdr.opcode =
+				VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
+
+	v->cvs_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d de-registering CVS cal\n", __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvs_wait,
+				 (v->cvs_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command  timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+
+}
+
+static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v)
+{
+	struct cvp_register_dev_cfg_cmd cvp_reg_dev_cfg_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvp_reg_dev_cfg_cmd, 0, sizeof(cvp_reg_dev_cfg_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvp) {
+		pr_err("%s: apr_cvp is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.cal_mem_handle) {
+		pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	get_vocproc_dev_cfg_cal(&cal_block);
+	if (cal_block.cal_size == 0) {
+		pr_err("%s: CVP cal size is 0\n", __func__);
+
+		goto fail;
+	}
+
+	cvp_reg_dev_cfg_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvp_reg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvp_reg_dev_cfg_cmd) - APR_HDR_SIZE);
+	cvp_reg_dev_cfg_cmd.hdr.src_port = v->session_id;
+	cvp_reg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+	cvp_reg_dev_cfg_cmd.hdr.token = 0;
+	cvp_reg_dev_cfg_cmd.hdr.opcode =
+					VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG;
+
+	cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_handle = common.cal_mem_handle;
+	cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address = cal_block.cal_paddr;
+	cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_size = cal_block.cal_size;
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvp,
+			   (uint32_t *) &cvp_reg_dev_cfg_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d registering CVP dev cfg cal\n",
+		       __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+				 (v->cvp_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v)
+{
+	struct cvp_deregister_dev_cfg_cmd cvp_dereg_dev_cfg_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvp_dereg_dev_cfg_cmd, 0, sizeof(cvp_dereg_dev_cfg_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+		goto fail;
+	}
+
+	get_vocproc_dev_cfg_cal(&cal_block);
+	if (cal_block.cal_size == 0)
+		return 0;
+
+	cvp_dereg_dev_cfg_cmd.hdr.hdr_field =
+				APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+					APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvp_dereg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvp_dereg_dev_cfg_cmd) - APR_HDR_SIZE);
+	cvp_dereg_dev_cfg_cmd.hdr.src_port = v->session_id;
+	cvp_dereg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+	cvp_dereg_dev_cfg_cmd.hdr.token = 0;
+	cvp_dereg_dev_cfg_cmd.hdr.opcode =
+				VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG;
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvp,
+			   (uint32_t *) &cvp_dereg_dev_cfg_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d de-registering CVP dev cfg cal\n",
+		       __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+				 (v->cvp_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
+{
+	struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvp_reg_cal_cmd, 0, sizeof(cvp_reg_cal_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvp) {
+		pr_err("%s: apr_cvp is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.cal_mem_handle) {
+		pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	get_all_vocproc_cal(&cal_block);
+	if (cal_block.cal_size == 0) {
+		pr_err("%s: CVP cal size is 0\n", __func__);
+
+		goto fail;
+	}
+
+	cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
+	cvp_reg_cal_cmd.hdr.src_port = v->session_id;
+	cvp_reg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+	cvp_reg_cal_cmd.hdr.token = 0;
+	cvp_reg_cal_cmd.hdr.opcode =
+				VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2;
+
+	cvp_reg_cal_cmd.cvp_cal_data.cal_mem_handle = common.cal_mem_handle;
+	cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address = cal_block.cal_paddr;
+	cvp_reg_cal_cmd.cvp_cal_data.cal_mem_size = cal_block.cal_size;
+
+	/* Get the column info corresponding to CVP cal from ACDB. */
+	get_voice_col_data(VOCPROC_CAL, &cal_block);
+	memcpy(&cvp_reg_cal_cmd.cvp_cal_data.column_info[0],
+	       (void *) cal_block.cal_kvaddr,
+	       cal_block.cal_size);
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_reg_cal_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d registering CVP cal\n", __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+				 (v->cvp_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
+{
+	struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvp_dereg_cal_cmd, 0, sizeof(cvp_dereg_cal_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+		goto fail;
+	}
+
+	get_all_vocproc_cal(&cal_block);
+	if (cal_block.cal_size == 0)
+		return 0;
+
+	cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
+	cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
+	cvp_dereg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+	cvp_dereg_cal_cmd.hdr.token = 0;
+	cvp_dereg_cal_cmd.hdr.opcode =
+				VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d de-registering CVP cal\n", __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+				 (v->cvp_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
+{
+	struct cvp_register_vol_cal_data_cmd cvp_reg_vol_cal_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvp_reg_vol_cal_cmd, 0, sizeof(cvp_reg_vol_cal_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.cal_mem_handle) {
+		pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	get_all_vocvol_cal(&cal_block);
+	if (cal_block.cal_size == 0) {
+		pr_err("%s: CVP vol cal size is 0\n", __func__);
+
+		goto fail;
+	}
+
+	cvp_reg_vol_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvp_reg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvp_reg_vol_cal_cmd) - APR_HDR_SIZE);
+	cvp_reg_vol_cal_cmd.hdr.src_port = v->session_id;
+	cvp_reg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+	cvp_reg_vol_cal_cmd.hdr.token = 0;
+	cvp_reg_vol_cal_cmd.hdr.opcode =
+			VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA;
+
+	cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_handle =
+							common.cal_mem_handle;
+	cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address =
+							cal_block.cal_paddr;
+	cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_size = cal_block.cal_size;
+
+	/* Get the column info corresponding to CVP volume cal from ACDB. */
+	get_voice_col_data(VOCVOL_CAL, &cal_block);
+	memcpy(&cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info[0],
+	       (void *) cal_block.cal_kvaddr,
+	       cal_block.cal_size);
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvp,
+			   (uint32_t *) &cvp_reg_vol_cal_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d registering CVP vol cal\n", __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+				 (v->cvp_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v)
+{
+	struct cvp_deregister_vol_cal_data_cmd cvp_dereg_vol_cal_cmd;
+	struct acdb_cal_block cal_block;
+	int ret = 0;
+	memset(&cvp_dereg_vol_cal_cmd, 0, sizeof(cvp_dereg_vol_cal_cmd));
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	if (!common.apr_q6_cvp) {
+		pr_err("%s: apr_cvp is NULL\n", __func__);
+
+		goto fail;
+	}
+
+	get_all_vocvol_cal(&cal_block);
+	if (cal_block.cal_size == 0)
+		return 0;
+
+	cvp_dereg_vol_cal_cmd.hdr.hdr_field =
+			APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	cvp_dereg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+				sizeof(cvp_dereg_vol_cal_cmd) - APR_HDR_SIZE);
+	cvp_dereg_vol_cal_cmd.hdr.src_port = v->session_id;
+	cvp_dereg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+	cvp_dereg_vol_cal_cmd.hdr.token = 0;
+	cvp_dereg_vol_cal_cmd.hdr.opcode =
+			VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA;
+
+	v->cvp_state = CMD_STATUS_FAIL;
+	ret = apr_send_pkt(common.apr_q6_cvp,
+			   (uint32_t *) &cvp_dereg_vol_cal_cmd);
+	if (ret < 0) {
+		pr_err("%s: Error %d de-registering CVP vol cal\n",
+		       __func__, ret);
+
+		goto fail;
+	}
+	ret = wait_event_timeout(v->cvp_wait,
+				 (v->cvp_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int voice_map_memory_physical_cmd(struct voice_data *v,
+					 struct mem_map_table *table_info,
+					 dma_addr_t phys,
+					 uint32_t size,
+					 uint32_t token)
 {
 	struct vss_imemory_cmd_map_physical_t mvm_map_phys_cmd;
 	uint32_t *memtable;
 	int ret = 0;
-	void *apr_mvm;
-	u16 mvm_handle;
 
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
-		return -EINVAL;
+
+		goto fail;
 	}
 
-	apr_mvm = common.apr_q6_mvm;
-
-	if (!apr_mvm) {
+	if (!common.apr_q6_mvm) {
 		pr_err("%s: apr_mvm is NULL.\n", __func__);
-		return -EINVAL;
+
+		goto fail;
 	}
 
-	if (!v->shmem_info.memtbl.data) {
-		pr_err("%s: shmem_info.memtbl.data is NULL.\n", __func__);
-		return -EINVAL;
+	if (!table_info->data) {
+		pr_err("%s: memory table is NULL.\n", __func__);
+
+		goto fail;
 	}
 
-	memtable = (uint32_t *)v->shmem_info.memtbl.data;
+	memtable = (uint32_t *) table_info->data;
 
 	/*
 	 * Store next table descriptor's address(64 bit) as NULL as there
@@ -1301,25 +1841,22 @@
 	memtable[2] = 0;
 
 	/* Store shared mem add */
-	memtable[3] = v->shmem_info.sh_buf.buf[0].phys;
+	memtable[3] = phys;
 	memtable[4] = 0;
 
 	/* Store shared memory size */
-	memtable[5] = v->shmem_info.sh_buf.buf[0].size * NUM_OF_BUFFERS;
-
-	mvm_handle = voice_get_mvm_handle(v);
+	memtable[5] = size;
 
 	mvm_map_phys_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
 	mvm_map_phys_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 				sizeof(mvm_map_phys_cmd) - APR_HDR_SIZE);
 	mvm_map_phys_cmd.hdr.src_port = v->session_id;
-	mvm_map_phys_cmd.hdr.dest_port = mvm_handle;
-	mvm_map_phys_cmd.hdr.token = 0;
+	mvm_map_phys_cmd.hdr.dest_port = voice_get_mvm_handle(v);
+	mvm_map_phys_cmd.hdr.token = token;
 	mvm_map_phys_cmd.hdr.opcode = VSS_IMEMORY_CMD_MAP_PHYSICAL;
 
-	mvm_map_phys_cmd.table_descriptor.mem_address =
-						v->shmem_info.memtbl.phys;
+	mvm_map_phys_cmd.table_descriptor.mem_address = table_info->phys;
 	mvm_map_phys_cmd.table_descriptor.mem_size =
 			sizeof(struct vss_imemory_block_t) +
 			sizeof(struct vss_imemory_table_descriptor_t);
@@ -1330,36 +1867,71 @@
 	mvm_map_phys_cmd.min_data_width = 8;
 	mvm_map_phys_cmd.max_data_width = 64;
 
-	pr_debug("%s: ntd->add: %lld, ntd->size: %d, table->add: 0x%x\n",
-		__func__,
-		*((uint64_t *)v->shmem_info.memtbl.data),
-		*(((uint32_t *)(v->shmem_info.memtbl.data)) + 2),
-		*(((uint32_t *)(v->shmem_info.memtbl.data)) + 3));
-	pr_debug("%s: table->size: %d, pkt_size: %d, mvm_handle: 0x%x\n",
-		__func__,
-		*(((uint32_t *)(v->shmem_info.memtbl.data)) + 5),
-		mvm_map_phys_cmd.hdr.pkt_size, mvm_handle);
+	pr_debug("%s: next table desc: add: %lld, size: %d\n",
+		 __func__, *((uint64_t *) memtable),
+		 *(((uint32_t *) memtable) + 2));
+	pr_debug("%s: phy add of of mem being mapped 0x%x, size: %d\n",
+		 __func__, *(((uint32_t *) memtable) + 3),
+		 *(((uint32_t *) memtable) + 5));
 
 	v->mvm_state = CMD_STATUS_FAIL;
-	ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_map_phys_cmd);
+	ret = apr_send_pkt(common.apr_q6_mvm, (uint32_t *) &mvm_map_phys_cmd);
 	if (ret < 0) {
-		pr_err("Fail: sending mvm map phy cmd %d\n", ret);
+		pr_err("%s: Error %d sending mvm map phy cmd\n", __func__, ret);
+
 		goto fail;
 	}
 
 	ret = wait_event_timeout(v->mvm_wait,
-			(v->mvm_state == CMD_STATUS_SUCCESS),
-			msecs_to_jiffies(TIMEOUT_MS));
+				 (v->mvm_state == CMD_STATUS_SUCCESS),
+				 msecs_to_jiffies(TIMEOUT_MS));
 	if (!ret) {
-		pr_err("%s: wait_event timeout %d\n", __func__, ret);
+		pr_err("%s: Command timeout\n", __func__);
+
 		goto fail;
 	}
 
 	return 0;
+
 fail:
 	return -EINVAL;
 }
 
+static int voice_mem_map_cal_block(struct voice_data *v)
+{
+	int ret = 0;
+	struct acdb_cal_block cal_block;
+
+	if (v == NULL) {
+		pr_err("%s: v is NULL\n", __func__);
+
+		return -EINVAL;
+	}
+
+	if (common.cal_mem_handle != 0) {
+		pr_debug("%s: Cal block already mem mapped\n", __func__);
+
+		return ret;
+	}
+
+	/* Get the physical address of calibration memory block from ACDB. */
+	get_voice_cal_allocation(&cal_block);
+
+	if (!cal_block.cal_paddr) {
+		pr_err("%s: Cal block not allocated\n", __func__);
+
+		return -EINVAL;
+	}
+
+	ret = voice_map_memory_physical_cmd(v,
+					    &common.cal_mem_map_table,
+					    cal_block.cal_paddr,
+					    cal_block.cal_size,
+					    VOC_CAL_MEM_MAP_TOKEN);
+
+	return ret;
+}
+
 static int voice_setup_vocproc(struct voice_data *v)
 {
 	struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
@@ -1437,6 +2009,12 @@
 		goto fail;
 	}
 
+	voice_send_cvs_register_cal_cmd(v);
+
+	voice_send_cvp_register_dev_cfg_cmd(v);
+	voice_send_cvp_register_cal_cmd(v);
+	voice_send_cvp_register_vol_cal_cmd(v);
+
 	/* enable vocproc */
 	ret = voice_send_enable_vocproc_cmd(v);
 	if (ret < 0)
@@ -1789,6 +2367,11 @@
 		goto fail;
 	}
 
+	voice_send_cvp_deregister_vol_cal_cmd(v);
+	voice_send_cvp_deregister_cal_cmd(v);
+	voice_send_cvp_deregister_dev_cfg_cmd(v);
+
+	voice_send_cvs_deregister_cal_cmd(v);
 
 	/* destrop cvp session */
 	cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1997,20 +2580,18 @@
 {
 	struct cvs_set_mute_cmd cvs_mute_cmd;
 	int ret = 0;
-	void *apr_cvs;
-	u16 cvs_handle;
 
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
-		return -EINVAL;
-	}
-	apr_cvs = common.apr_q6_cvs;
 
-	if (!apr_cvs) {
-		pr_err("%s: apr_cvs is NULL.\n", __func__);
-		return -EINVAL;
+		goto fail;
 	}
-	cvs_handle = voice_get_cvs_handle(v);
+
+	if (!common.apr_q6_cvs) {
+		pr_err("%s: apr_cvs is NULL.\n", __func__);
+
+		goto fail;
+	}
 
 	/* send mute/unmute to cvs */
 	cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -2019,25 +2600,31 @@
 	cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
 	cvs_mute_cmd.hdr.src_port = v->session_id;
-	cvs_mute_cmd.hdr.dest_port = cvs_handle;
+	cvs_mute_cmd.hdr.dest_port = voice_get_cvs_handle(v);
 	cvs_mute_cmd.hdr.token = 0;
-	cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
-	cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
+	cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
+	cvs_mute_cmd.cvs_set_mute.direction = VSS_IVOLUME_DIRECTION_TX;
 	cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
+	cvs_mute_cmd.cvs_set_mute.ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
 
 	v->cvs_state = CMD_STATUS_FAIL;
-	ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
+	ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_mute_cmd);
 	if (ret < 0) {
-		pr_err("Fail: send STREAM SET MUTE\n");
+		pr_err("%s: Error %d sending stream mute\n", __func__, ret);
+
 		goto fail;
 	}
 	ret = wait_event_timeout(v->cvs_wait,
 				 (v->cvs_state == CMD_STATUS_SUCCESS),
 				 msecs_to_jiffies(TIMEOUT_MS));
-	if (!ret)
-		pr_err("%s: wait_event timeout\n", __func__);
+	if (!ret) {
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
+	}
 
 	return 0;
+
 fail:
 	return -EINVAL;
 }
@@ -2046,19 +2633,18 @@
 {
 	struct cvp_set_mute_cmd cvp_mute_cmd;
 	int ret = 0;
-	void *apr_cvp;
-	u16 cvp_handle;
+
 	if (v == NULL) {
 		pr_err("%s: v is NULL\n", __func__);
-		return -EINVAL;
-	}
-	apr_cvp = common.apr_q6_cvp;
 
-	if (!apr_cvp) {
-		pr_err("%s: apr_cvp is NULL.\n", __func__);
-		return -EINVAL;
+		goto fail;
 	}
-	cvp_handle = voice_get_cvp_handle(v);
+
+	if (!common.apr_q6_cvp) {
+		pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+		goto fail;
+	}
 
 	cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
 						APR_HDR_LEN(APR_HDR_SIZE),
@@ -2066,25 +2652,32 @@
 	cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
 					sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
 	cvp_mute_cmd.hdr.src_port = v->session_id;
-	cvp_mute_cmd.hdr.dest_port = cvp_handle;
+	cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v);
 	cvp_mute_cmd.hdr.token = 0;
-	cvp_mute_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_MUTE;
-	cvp_mute_cmd.cvp_set_mute.direction = 1;
+	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;
+
 	v->cvp_state = CMD_STATUS_FAIL;
-	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_mute_cmd);
+	ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_mute_cmd);
 	if (ret < 0) {
-		pr_err("Fail in sending RX device mute cmd\n");
-		return -EINVAL;
+		pr_err("%s: Error %d sending rx device cmd\n", __func__, ret);
+
+		goto fail;
 	}
 	ret = wait_event_timeout(v->cvp_wait,
 				 (v->cvp_state == CMD_STATUS_SUCCESS),
 				 msecs_to_jiffies(TIMEOUT_MS));
 	if (!ret) {
-		pr_err("%s: wait_event timeout\n", __func__);
-		return -EINVAL;
+		pr_err("%s: Command timeout\n", __func__);
+
+		goto fail;
 	}
+
 	return 0;
+
+fail:
+	return -EINVAL;
 }
 
 static int voice_send_vol_index_cmd(struct voice_data *v)
@@ -2569,6 +3162,9 @@
 			goto fail;
 		}
 
+		voice_send_cvp_deregister_vol_cal_cmd(v);
+		voice_send_cvp_deregister_cal_cmd(v);
+		voice_send_cvp_deregister_dev_cfg_cmd(v);
 
 		v->voc_state = VOC_CHANGE;
 	}
@@ -2598,6 +3194,10 @@
 			goto fail;
 		}
 
+		voice_send_cvp_register_dev_cfg_cmd(v);
+		voice_send_cvp_register_cal_cmd(v);
+		voice_send_cvp_register_vol_cal_cmd(v);
+
 	ret = voice_send_enable_vocproc_cmd(v);
 	if (ret < 0) {
 		pr_err("%s: enable vocproc failed %d\n", __func__, ret);
@@ -2985,8 +3585,21 @@
 			pr_err("create mvm and cvs failed\n");
 			goto fail;
 		}
+
+		/* Memory map the calibration memory block. */
+		ret = voice_mem_map_cal_block(v);
+		if (ret < 0) {
+			pr_err("%s: Memory map of cal block failed %d\n",
+			       __func__, ret);
+			/* Allow call to continue, call quality will be bad. */
+		}
+
 		if (is_voip_session(session_id)) {
-			ret = voice_send_mvm_map_memory_physical_cmd(v);
+			ret = voice_map_memory_physical_cmd(v,
+			      &v->shmem_info.memtbl,
+			      v->shmem_info.sh_buf.buf[0].phys,
+			      v->shmem_info.sh_buf.buf[0].size * NUM_OF_BUFFERS,
+			      VOIP_MEM_MAP_TOKEN);
 			if (ret) {
 				pr_err("%s: mvm_map_memory_phy failed %d\n",
 					__func__, ret);
@@ -3132,7 +3745,8 @@
 		}
 	} else if (data->opcode == VSS_IMEMORY_RSP_MAP) {
 		pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__);
-		if (data->payload_size) {
+
+		if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) {
 			ptr = data->payload;
 			if (ptr[0]) {
 				v->shmem_info.mem_handle = ptr[0];
@@ -3141,6 +3755,21 @@
 				v->mvm_state = CMD_STATUS_SUCCESS;
 				wake_up(&v->mvm_wait);
 			}
+		} else if (data->payload_size &&
+			   data->token == VOC_CAL_MEM_MAP_TOKEN) {
+			ptr = data->payload;
+			if (ptr[0]) {
+				c->cal_mem_handle = ptr[0];
+
+				pr_debug("%s: cal mem handle 0x%x\n",
+					 __func__, c->cal_mem_handle);
+
+				v->mvm_state = CMD_STATUS_SUCCESS;
+				wake_up(&v->mvm_wait);
+			}
+		} else {
+			pr_err("%s: Unknown mem map token %d\n",
+			       __func__, data->token);
 		}
 	}
 	return 0;
@@ -3204,14 +3833,14 @@
 				v->cvs_state = CMD_STATUS_SUCCESS;
 				wake_up(&v->cvs_wait);
 				break;
-			case VSS_ISTREAM_CMD_SET_MUTE:
+			case VSS_IVOLUME_CMD_MUTE_V2:
 			case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
 			case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
 			case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
 			case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
 			case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
 			case APRV2_IBASIC_CMD_DESTROY_SESSION:
-			case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
+			case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2:
 			case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
 			case VSS_ICOMMON_CMD_MAP_MEMORY:
 			case VSS_ICOMMON_CMD_UNMAP_MEMORY:
@@ -3410,13 +4039,15 @@
 			case VSS_IVOCPROC_CMD_ENABLE:
 			case VSS_IVOCPROC_CMD_DISABLE:
 			case APRV2_IBASIC_CMD_DESTROY_SESSION:
-			case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
-			case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
-			case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
+			case VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA:
+			case VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA:
+			case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2:
 			case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
+			case VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG:
+			case VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG:
 			case VSS_ICOMMON_CMD_MAP_MEMORY:
 			case VSS_ICOMMON_CMD_UNMAP_MEMORY:
-			case VSS_IVOCPROC_CMD_SET_MUTE:
+			case VSS_IVOLUME_CMD_MUTE_V2:
 				v->cvp_state = CMD_STATUS_SUCCESS;
 				wake_up(&v->cvp_wait);
 				break;
@@ -3564,6 +4195,74 @@
 	return -EINVAL;
 }
 
+static int voice_alloc_cal_mem_map_table(void)
+{
+	int ret = 0;
+	int len;
+
+	common.cal_mem_map_table.client = msm_ion_client_create(UINT_MAX,
+								"voc_client");
+
+	if (IS_ERR_OR_NULL((void *) common.cal_mem_map_table.client)) {
+		pr_err("%s: ION create client for cal mem map table failed\n",
+		       __func__);
+
+		goto err;
+	}
+
+	common.cal_mem_map_table.handle =
+				ion_alloc(common.cal_mem_map_table.client,
+					  sizeof(struct vss_imemory_table_t),
+					  SZ_4K, (0x1 << ION_AUDIO_HEAP_ID), 0);
+	if (IS_ERR_OR_NULL((void *) common.cal_mem_map_table.handle)) {
+		pr_err("%s: ION memory alloc for cal mem map table failed\n",
+		       __func__);
+
+		goto err_ion_client;
+	}
+
+	ret = ion_phys(common.cal_mem_map_table.client,
+		      common.cal_mem_map_table.handle,
+		      (ion_phys_addr_t *) &common.cal_mem_map_table.phys,
+		      (size_t *) &len);
+	if (ret) {
+		pr_err("%s: Phy addr for cal mem map table failed %d\n",
+		       __func__, ret);
+
+		goto err_ion_handle;
+	}
+
+	common.cal_mem_map_table.data =
+				ion_map_kernel(common.cal_mem_map_table.client,
+					       common.cal_mem_map_table.handle);
+	if (IS_ERR_OR_NULL((void *) common.cal_mem_map_table.data)) {
+		pr_err("%s: Virtual addr for cal memory map table failed\n",
+		       __func__);
+
+		goto err_ion_handle;
+	}
+
+	memset(common.cal_mem_map_table.data, 0,
+	       sizeof(struct vss_imemory_table_t));
+
+	common.cal_mem_map_table.size = sizeof(struct vss_imemory_table_t);
+
+	pr_debug("%s: data 0x%x phys 0x%x\n", __func__,
+		 (unsigned int) common.cal_mem_map_table.data,
+		 common.cal_mem_map_table.phys);
+
+	return 0;
+
+err_ion_handle:
+	ion_free(common.cal_mem_map_table.client,
+		 common.cal_mem_map_table.handle);
+err_ion_client:
+	ion_client_destroy(common.cal_mem_map_table.client);
+	memset(&common.cal_mem_map_table, 0, sizeof(common.cal_mem_map_table));
+err:
+	return -EINVAL;
+}
+
 static int __init voice_init(void)
 {
 	int rc = 0, i = 0;
@@ -3612,6 +4311,9 @@
 			pr_err("failed to alloc mem map talbe %d\n", rc);
 	}
 
+	/* Allocate memory for calibration memory map table. */
+	rc = voice_alloc_cal_mem_map_table();
+
 	return rc;
 }
 
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index df0cbec..9f82694 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -25,6 +25,8 @@
  */
 #define BUFFER_BLOCK_SIZE       4096
 
+#define MAX_COL_INFO_SIZE	324
+
 #define VOC_REC_UPLINK		0x00
 #define VOC_REC_DOWNLINK	0x01
 #define VOC_REC_BOTH		0x02
@@ -437,9 +439,13 @@
 
 #define APRV2_IBASIC_CMD_DESTROY_SESSION		0x0001003C
 
-#define VSS_ISTREAM_CMD_SET_MUTE			0x00011022
+/*
+ * This command changes the mute setting. The new mute setting will
+ * be applied over the specified ramp duration.
+ */
+#define VSS_IVOLUME_CMD_MUTE_V2				0x0001138B
 
-#define VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA	0x00011279
+#define VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2    0x00011369
 
 #define VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA     0x0001127A
 
@@ -541,22 +547,33 @@
 	*/
 } __packed;
 
-struct vss_istream_cmd_set_mute_t {
+#define VSS_IVOLUME_DIRECTION_TX	0
+#define VSS_IVOLUME_DIRECTION_RX	1
+
+#define VSS_IVOLUME_MUTE_OFF		0
+#define VSS_IVOLUME_MUTE_ON		1
+
+#define DEFAULT_MUTE_RAMP_DURATION	500
+
+struct vss_ivolume_cmd_mute_v2_t {
 	uint16_t direction;
-	/**<
-	* 0 : TX only
-	* 1 : RX only
-	* 2 : TX and Rx
-	*/
+	/*
+	 * The direction field sets the direction to apply the mute command.
+	 * The Supported values:
+	 * VSS_IVOLUME_DIRECTION_TX
+	 * VSS_IVOLUME_DIRECTION_RX
+	 */
 	uint16_t mute_flag;
-	/**<
-	* Mute, un-mute.
-	*
-	* 0 : Silence disable
-	* 1 : Silence enable
-	* 2 : CNG enable. Applicable to TX only. If set on RX behavior
-	*     will be the same as 1
-	*/
+	/*
+	 * Turn mute on or off. The Supported values:
+	 * VSS_IVOLUME_MUTE_OFF
+	 * VSS_IVOLUME_MUTE_ON
+	 */
+	uint16_t ramp_duration_ms;
+	/*
+	 * Mute change ramp duration in milliseconds.
+	 * The Supported values: 0 to 5000.
+	 */
 } __packed;
 
 struct vss_istream_cmd_create_full_control_session_t {
@@ -666,14 +683,21 @@
 	 */
 } __packed;
 
-struct vss_istream_cmd_register_calibration_data_t {
-	uint32_t phys_addr;
-	/* Phsical address to be registered with stream. The calibration data
-	 *  is stored at this address.
-	 */
-	uint32_t mem_size;
+struct vss_istream_cmd_register_calibration_data_v2_t {
+	uint32_t cal_mem_handle;
+	/* Handle to the shared memory that holds the calibration data. */
+	uint64_t cal_mem_address;
+	/* Location of calibration data. */
+	uint32_t cal_mem_size;
 	/* Size of the calibration data in bytes. */
-};
+	uint8_t column_info[MAX_COL_INFO_SIZE];
+	/*
+	 * Column info contains the number of columns and the array of columns
+	 * in the calibration table. The order in which the columns are provided
+	 * here must match the order in which they exist in the calibration
+	 * table provided.
+	 */
+} __packed;
 
 struct vss_icommon_cmd_set_ui_property_enable_t {
 	uint32_t module_id;
@@ -705,7 +729,7 @@
 
 struct cvs_set_mute_cmd {
 	struct apr_hdr hdr;
-	struct vss_istream_cmd_set_mute_t cvs_set_mute;
+	struct vss_ivolume_cmd_mute_v2_t cvs_set_mute;
 } __packed;
 
 struct cvs_set_media_type_cmd {
@@ -740,7 +764,7 @@
 
 struct cvs_register_cal_data_cmd {
 	struct apr_hdr hdr;
-	struct vss_istream_cmd_register_calibration_data_t cvs_cal_data;
+	struct vss_istream_cmd_register_calibration_data_v2_t cvs_cal_data;
 } __packed;
 
 struct cvs_deregister_cal_data_cmd {
@@ -797,11 +821,24 @@
 #define VSS_IVOCPROC_CMD_DISABLE			0x000110E1
 /**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */
 
-#define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA	0x00011275
-#define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA    0x00011276
+/*
+ * Registers the memory that contains device specific configuration data with
+ * the vocproc. The client must register device configuration data with the
+ * vocproc that corresponds with the device being set on the vocproc.
+ */
+#define VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG		0x00011371
 
-#define VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE      0x00011277
-#define VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE    0x00011278
+/*
+ * Deregisters the memory that holds device configuration data from the
+  vocproc.
+*/
+#define VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG	0x00011372
+
+#define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2	0x00011373
+#define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA	0x00011276
+
+#define VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA	0x00011374
+#define VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA	0x00011375
 
 #define VSS_IVOCPROC_TOPOLOGY_ID_NONE			0x00010F70
 #define VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS		0x00010F71
@@ -847,8 +884,6 @@
 #define VSS_MEDIA_ID_4GV_WB_MODEM	0x00010FC4
 /*CDMA EVRC-WB vocoder modem format */
 
-#define VSS_IVOCPROC_CMD_SET_MUTE			0x000110EF
-
 #define VOICE_CMD_SET_PARAM				0x00011006
 #define VOICE_CMD_GET_PARAM				0x00011007
 #define VOICE_EVT_GET_PARAM_ACK				0x00011008
@@ -941,39 +976,54 @@
 	 */
 } __packed;
 
-struct vss_ivocproc_cmd_register_calibration_data_t {
-	uint32_t phys_addr;
-	/* Phsical address to be registered with vocproc. Calibration data
-	 *  is stored at this address.
+struct vss_ivocproc_cmd_register_device_config_t {
+	uint32_t mem_handle;
+	/*
+	 * Handle to the shared memory that holds the per-network calibration
+	 * data.
 	 */
+	uint64_t mem_address;
+	/* Location of calibration data. */
 	uint32_t mem_size;
 	/* Size of the calibration data in bytes. */
 } __packed;
 
-struct vss_ivocproc_cmd_register_volume_cal_table_t {
-	uint32_t phys_addr;
-	/* Phsical address to be registered with the vocproc. The volume
-	 *  calibration table is stored at this location.
+struct vss_ivocproc_cmd_register_calibration_data_v2_t {
+	uint32_t cal_mem_handle;
+	/*
+	 * Handle to the shared memory that holds the per-network calibration
+	 * data.
 	 */
-
-	uint32_t mem_size;
-	/* Size of the volume calibration table in bytes. */
+	uint64_t cal_mem_address;
+	/* Location of calibration data. */
+	uint32_t cal_mem_size;
+	/* Size of the calibration data in bytes. */
+	uint8_t column_info[MAX_COL_INFO_SIZE];
+	/*
+	 * Column info contains the number of columns and the array of columns
+	 * in the calibration table. The order in which the columns are provided
+	 * here must match the order in which they exist in the calibration
+	 * table provided.
+	 */
 } __packed;
 
-struct vss_ivocproc_cmd_set_mute_t {
-	uint16_t direction;
+struct vss_ivocproc_cmd_register_volume_cal_data_t {
+	uint32_t cal_mem_handle;
 	/*
-	* 0 : TX only.
-	* 1 : RX only.
-	* 2 : TX and Rx.
-	*/
-	uint16_t mute_flag;
+	 * Handle to the shared memory that holds the volume calibration
+	 * data.
+	 */
+	uint64_t cal_mem_address;
+	/* Location of volume calibration data. */
+	uint32_t cal_mem_size;
+	/* Size of the volume calibration data in bytes. */
+	uint8_t column_info[MAX_COL_INFO_SIZE];
 	/*
-	* Mute, un-mute.
-	*
-	* 0 : Disable.
-	* 1 : Enable.
-	*/
+	 * Column info contains the number of columns and the array of columns
+	 * in the calibration table. The order in which the columns are provided
+	 * here must match the order in which they exist in the calibration
+	 * table provided.
+	 */
 } __packed;
 
 struct cvp_create_full_ctl_session_cmd {
@@ -999,27 +1049,36 @@
 	struct vss_ivocproc_cmd_set_volume_index_t cvp_set_vol_idx;
 } __packed;
 
+struct cvp_register_dev_cfg_cmd {
+	struct apr_hdr hdr;
+	struct vss_ivocproc_cmd_register_device_config_t cvp_dev_cfg_data;
+} __packed;
+
+struct cvp_deregister_dev_cfg_cmd {
+	struct apr_hdr hdr;
+} __packed;
+
 struct cvp_register_cal_data_cmd {
 	struct apr_hdr hdr;
-	struct vss_ivocproc_cmd_register_calibration_data_t cvp_cal_data;
+	struct vss_ivocproc_cmd_register_calibration_data_v2_t cvp_cal_data;
 } __packed;
 
 struct cvp_deregister_cal_data_cmd {
 	struct apr_hdr hdr;
 } __packed;
 
-struct cvp_register_vol_cal_table_cmd {
+struct cvp_register_vol_cal_data_cmd {
 	struct apr_hdr hdr;
-	struct vss_ivocproc_cmd_register_volume_cal_table_t cvp_vol_cal_tbl;
+	struct vss_ivocproc_cmd_register_volume_cal_data_t cvp_vol_cal_data;
 } __packed;
 
-struct cvp_deregister_vol_cal_table_cmd {
+struct cvp_deregister_vol_cal_data_cmd {
 	struct apr_hdr hdr;
 } __packed;
 
 struct cvp_set_mute_cmd {
 	struct apr_hdr hdr;
-	struct vss_ivocproc_cmd_set_mute_t cvp_set_mute;
+	struct vss_ivolume_cmd_mute_v2_t cvp_set_mute;
 } __packed;
 
 /* CB for up-link packets. */
@@ -1130,7 +1189,8 @@
 	/* APR to CVP in the Q6 */
 	void *apr_q6_cvp;
 
-	struct ion_client *client;
+	struct mem_map_table cal_mem_map_table;
+	uint32_t cal_mem_handle;
 	struct cal_mem cvp_cal;
 	struct cal_mem cvs_cal;