Merge "msm: 8610: Compile Low power management drivers"
diff --git a/Documentation/devicetree/bindings/coresight/coresight.txt b/Documentation/devicetree/bindings/coresight/coresight.txt
index f860618..b3037d8 100644
--- a/Documentation/devicetree/bindings/coresight/coresight.txt
+++ b/Documentation/devicetree/bindings/coresight/coresight.txt
@@ -32,6 +32,7 @@
 - coresight-child-ports : list of input port numbers of the children
 - coresight-default-sink : represents the default compile time CoreSight sink
 - qcom,pc-save : program counter save implemented
+- qcom,blk-size : block size for tmc-etr to usb transfers
 
 Examples:
 
diff --git a/Documentation/devicetree/bindings/power/bq28400-battery.txt b/Documentation/devicetree/bindings/power/bq28400-battery.txt
index 1460d70..a95e61f 100644
--- a/Documentation/devicetree/bindings/power/bq28400-battery.txt
+++ b/Documentation/devicetree/bindings/power/bq28400-battery.txt
@@ -4,15 +4,20 @@
 The device interface is I2C, its I2C slave 7-bit address is 0xb.
 The device is usually embedded inside the "smart battery" pack.
 
-node required properties:
-- compatible:	Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
-- reg:		I2C Address must be 0xb.
+Required properties:
+
+ - compatible : Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
+ - reg : I2C Address must be 0xb.
+ - ti,temp-cold : Cold temperature limit in celsius degree
+ - ti,temp-hot : Hot temperature limit in celsius degree
 
 Example:
 	i2c@f9967000 {
 		battery@b {
 			compatible = "ti,bq28400-battery", "ti,bq30z55-battery";
 			reg = <0xb>;
+			ti,temp-cold = <2>;
+			ti,temp-hot = <43>;
 		};
 	};
 
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
index e3da903..149445d 100644
--- a/Documentation/devicetree/bindings/regulator/krait-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -10,10 +10,17 @@
 				"mdd" - string to identify the area where mdd registers reside.
 - qcom,headroom-voltage:	The minimum required voltage drop between the input
 			 	voltage and the output voltage for the LDO to be
-			 	operational, in microvolts
-- qcom,retention-voltage:	The value for retention voltage in microvolts
-- qcom,ldo-default-voltage:	The default value for LDO voltage in microvolts
-- qcom,ldo-threshold-voltage:	The voltage value above which LDO is nonfunctional
+			 	operational, in microvolts. Acceptable values are from
+				50000uV to 250000uV
+- qcom,retention-voltage:	The value for retention voltage in microvolts. Acceptable
+				values are from 465000uV to 750000uV
+- qcom,ldo-default-voltage:	The default value for LDO voltage in microvolts. Acceptable
+				values are from 465000uV to 750000uV
+- qcom,ldo-threshold-voltage:	The voltage value above which LDO is nonfunctional.
+				Acceptable values are from 600000uV to 900000uV
+- qcom,ldo-delta-voltage:	The delta used to reduce the requested voltage in order
+				to derive the LDO output voltage while switching
+				to LDO mode. Acceptable values are from 1000uV to 100000uV
 
 Any property defined as part of the core regulator
 binding, defined in regulator.txt, can also be used.
@@ -31,5 +38,6 @@
 		qcom,retention-voltage = <745000>;
 		qcom,ldo-default-voltage = <745000>;
 		qcom,ldo-threshold-voltage = <750000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
diff --git a/arch/arm/boot/dts/msm-iommu.dtsi b/arch/arm/boot/dts/msm-iommu.dtsi
index 5a9e1ee..9bb642d 100755
--- a/arch/arm/boot/dts/msm-iommu.dtsi
+++ b/arch/arm/boot/dts/msm-iommu.dtsi
@@ -40,8 +40,8 @@
 					0x2010
 					0x2014>;
 
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+		qcom,iommu-bfb-data =  <0x0000ffff
+					0x0
 					0x4
 					0x4
 					0x0
@@ -111,7 +111,7 @@
 					0x2020>;
 
 		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+					0x0
 					0x00000004
 					0x00000010
 					0x00000000
@@ -261,8 +261,8 @@
 					0x2414
 					0x2008>;
 
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+		qcom,iommu-bfb-data =  <0x00000003
+					0x0
 					0x00000004
 					0x00000010
 					0x00000000
@@ -322,7 +322,7 @@
 					0x2020>;
 
 		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+					0x00000000
 					0x4
 					0x8
 					0x0
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 9c198ec..06bab30 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -269,6 +269,11 @@
 	status = "ok";
 };
 
+&ehci {
+	status = "ok";
+	vbus-supply = <&usb2_otg_sw>;
+};
+
 &usb3 {
 	qcom,otg-capability;
 };
diff --git a/arch/arm/boot/dts/msm8974-coresight.dtsi b/arch/arm/boot/dts/msm8974-coresight.dtsi
index ee3df10..6bb7b28 100644
--- a/arch/arm/boot/dts/msm8974-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8974-coresight.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -190,5 +190,7 @@
 		coresight-id = <14>;
 		coresight-name = "coresight-csr";
 		coresight-nr-inports = <0>;
+
+		qcom,blk-size = <3>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index 7e1f438..f15f572 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -285,8 +285,6 @@
 &pm8941_chg {
 	status = "ok";
 
-	qcom,chg-charging-disabled;
-
 	qcom,chg-chgr@1000 {
 		status = "ok";
 	};
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 7368788..f0f79b0 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -26,6 +26,8 @@
 		battery@b {
 			compatible = "ti,bq28400-battery";
 			reg = <0xb>;
+			ti,temp-cold = <2>; /* degree celsius */
+			ti,temp-hot = <43>; /* degree celsius */
 		};
 
 		charger@2b {
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index dc52fda6..40eaf2d 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -272,8 +272,6 @@
 &pm8941_chg {
 	status = "ok";
 
-	qcom,chg-charging-disabled;
-
 	qcom,chg-chgr@1000 {
 		status = "ok";
 	};
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-pm.dtsi
index 1302ccb..ab105a9 100644
--- a/arch/arm/boot/dts/msm8974-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-pm.dtsi
@@ -179,6 +179,8 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		qcom,use-qtimer;
+
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 5fa2364..c6c5452 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -434,7 +434,8 @@
 		qcom,headroom-voltage = <150000>;
 		qcom,retention-voltage = <675000>;
 		qcom,ldo-default-voltage = <750000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	krait1_vreg: regulator@f9098000 {
@@ -448,7 +449,8 @@
 		qcom,headroom-voltage = <150000>;
 		qcom,retention-voltage = <675000>;
 		qcom,ldo-default-voltage = <750000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	krait2_vreg: regulator@f90a8000 {
@@ -462,7 +464,8 @@
 		qcom,headroom-voltage = <150000>;
 		qcom,retention-voltage = <675000>;
 		qcom,ldo-default-voltage = <750000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	krait3_vreg: regulator@f90b8000 {
@@ -476,7 +479,8 @@
 		qcom,headroom-voltage = <150000>;
 		qcom,retention-voltage = <675000>;
 		qcom,ldo-default-voltage = <750000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	spi_eth_vreg: spi_eth_phy_vreg {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index d3a3e03..1072e7e 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -672,6 +672,19 @@
 				<61 512 240000 960000>;
 	};
 
+	ehci: qcom,ehci-host@f9a55000 {
+		compatible = "qcom,ehci-host";
+		status = "disabled";
+		reg = <0xf9a55000 0x400>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		HSUSB_VDDCX-supply = <&pm8841_s2>;
+		HSUSB_1p8-supply = <&pm8941_l6>;
+		HSUSB_3p3-supply = <&pm8941_l24>;
+		qcom,usb2-enable-hsphy2;
+		qcom,usb2-power-budget = <500>;
+	};
+
 	gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
 		parent-supply = <&pm8841_s4_corner>;
 	};
diff --git a/arch/arm/boot/dts/msm9625-coresight.dtsi b/arch/arm/boot/dts/msm9625-coresight.dtsi
index 9a49c32..f352c3f 100644
--- a/arch/arm/boot/dts/msm9625-coresight.dtsi
+++ b/arch/arm/boot/dts/msm9625-coresight.dtsi
@@ -126,5 +126,7 @@
 		coresight-id = <9>;
 		coresight-name = "coresight-csr";
 		coresight-nr-inports = <0>;
+
+		qcom,blk-size = <1>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
index 71fcfd6..5a925cb 100644
--- a/arch/arm/boot/dts/msm9625-pm.dtsi
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -71,6 +71,8 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		qcom,use-qtimer;
+
 		qcom,lpm-level@0 {
 			reg = <0x0>;
 			qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 3dfbd8a..c2ed824 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -609,6 +609,12 @@
 			<0xfc330000 0x1000>;
 		reg-names = "etm-base","debug-base";
 	};
+
+	qcom,msm-rtb {
+		compatible = "qcom,msm-rtb";
+		qcom,memory-reservation-type = "EBI1";
+		qcom,memory-reservation-size = <0x1000>; /* 4K EBI1 buffer */
+	};
 };
 
 /include/ "msm-pm8019-rpm-regulator.dtsi"
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index fda9074..ecf1c68 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -217,6 +217,9 @@
 CONFIG_USB_GADGET=y
 CONFIG_USB_CI13XXX_MSM=y
 CONFIG_USB_G_ANDROID=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MSM_HSIC=y
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -302,3 +305,4 @@
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MSM_RTB=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 0cc17b8..5cf6bd2 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -289,6 +289,7 @@
 	select DONT_MAP_HOLE_AFTER_MEMBANK0
 	select SENSORS_ADSP
 	select MSM_ULTRASOUND_B
+	select MSM_LPM_TEST
 
 config ARCH_MPQ8092
 	bool "MPQ8092"
@@ -955,6 +956,15 @@
 	help
 	  Support for the Qualcomm APQ8064 CDP device.
 
+config MACH_FSM8064_EP
+	depends on ARCH_APQ8064
+	bool "FSM8064 EP"
+	help
+	  Support for the Qualcomm FSM8064 EP device.
+	  This board also known as Femto development platform (FDP)
+	  is based on APQ8064 chipset. This board does not support
+	  keyboard, display or multimedia.
+
 config MACH_APQ8064_MTP
 	depends on ARCH_APQ8064
 	bool "APQ8064 MTP"
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 336c2fc..c4d9048 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -38,6 +38,7 @@
 obj-$(CONFIG_ARCH_MSM9625) += pmu.o perf_event_msm_pl310.o
 obj-$(CONFIG_ARCH_MSM8625) += pmu.o perf_event_msm_pl310.o
 obj-$(CONFIG_ARCH_MSM9615) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_DEBUG_FS) += perf_debug.o
 endif
 
 ifndef CONFIG_MSM_SMP
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 476a191..dc9120a 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -143,6 +143,11 @@
 #define PCIE_PWR_EN_PMIC_GPIO 13
 #define PCIE_RST_N_PMIC_MPP 1
 
+/* PCIe pmic gpios for fsm8064_ep */
+/* Unused pin. The WAKE feature is not supported on fsm8064_ep */
+#define PCIE_EP_WAKE_N_PMIC_GPIO	11
+#define PCIE_EP_RST_N_PMIC_GPIO		37
+
 #ifdef CONFIG_KERNEL_MSM_CONTIG_MEM_REGION
 static unsigned msm_contig_mem_size = MSM_CONTIG_MEM_SIZE;
 static int __init msm_contig_mem_size_setup(char *p)
@@ -959,7 +964,7 @@
 {
 	if (machine_is_apq8064_liquid() || machine_is_mpq8064_cdp() ||
 		machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv() ||
-					machine_is_apq8064_cdp()) {
+			machine_is_apq8064_cdp() || machine_is_fsm8064_ep()) {
 		if (machine_is_apq8064_liquid())
 			msm_ehci_host_pdata3.dock_connect_irq =
 					PM8921_MPP_IRQ(PM8921_IRQ_BASE, 9);
@@ -2479,6 +2484,19 @@
 	.wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_WAKE_N_PMIC_GPIO),
 };
 
+/* FSM8064_EP PCIe gpios */
+static struct msm_pcie_gpio_info_t ep_pcie_gpio_info[MSM_PCIE_MAX_GPIO] = {
+	{"rst_n", PM8921_GPIO_PM_TO_SYS(PCIE_EP_RST_N_PMIC_GPIO), 0},
+	{"pwr_en", PM8921_GPIO_PM_TO_SYS(PCIE_PWR_EN_PMIC_GPIO), 1},
+};
+
+static struct msm_pcie_platform ep_pcie_platform_data = {
+	.gpio = ep_pcie_gpio_info,
+	.axi_addr = PCIE_AXI_BAR_PHYS,
+	.axi_size = PCIE_AXI_BAR_SIZE,
+	.wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_EP_WAKE_N_PMIC_GPIO),
+};
+
 static int __init mpq8064_pcie_enabled(void)
 {
 	return !((readl_relaxed(QFPROM_RAW_FEAT_CONFIG_ROW0_MSB) & BIT(21)) ||
@@ -2493,6 +2511,12 @@
 	}
 }
 
+static void __init fsm8064_ep_pcie_init(void)
+{
+	msm_device_pcie.dev.platform_data = &ep_pcie_platform_data;
+	platform_device_register(&msm_device_pcie);
+}
+
 static struct platform_device mpq8064_device_ext_3p3v_vreg = {
 	.name			= "reg-fixed-voltage",
 	.dev			= {
@@ -2588,6 +2612,100 @@
 	&mpq_cpudai_pseudo,
 };
 
+static struct platform_device *ep_devices[] __initdata = {
+	&msm_device_smd_apq8064,
+	&apq8064_device_gadget_peripheral,
+	&apq8064_device_hsusb_host,
+	&android_usb_device,
+	&msm_device_wcnss_wlan,
+	&msm_device_iris_fm,
+	&apq8064_fmem_device,
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	&apq8064_android_pmem_device,
+	&apq8064_android_pmem_adsp_device,
+	&apq8064_android_pmem_audio_device,
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
+#ifdef CONFIG_ION_MSM
+	&apq8064_ion_dev,
+#endif
+	&msm8064_device_watchdog,
+	&msm8064_device_saw_regulator_core0,
+	&msm8064_device_saw_regulator_core1,
+	&msm8064_device_saw_regulator_core2,
+	&msm8064_device_saw_regulator_core3,
+#if defined(CONFIG_QSEECOM)
+	&qseecom_device,
+#endif
+
+	&msm_8064_device_tsif[0],
+	&msm_8064_device_tsif[1],
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+	&qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+	&qcedev_device,
+#endif
+
+#ifdef CONFIG_HW_RANDOM_MSM
+	&apq8064_device_rng,
+#endif
+	&apq_pcm,
+	&apq_pcm_routing,
+	&apq8064_rpm_device,
+	&apq8064_rpm_log_device,
+	&apq8064_rpm_stat_device,
+	&apq8064_rpm_master_stat_device,
+	&apq_device_tz_log,
+	&msm_bus_8064_apps_fabric,
+	&msm_bus_8064_sys_fabric,
+	&msm_bus_8064_mm_fabric,
+	&msm_bus_8064_sys_fpb,
+	&msm_bus_8064_cpss_fpb,
+	&msm_pil_dsps,
+	&msm_8960_q6_lpass,
+	&msm_pil_vidc,
+	&msm_gss,
+	&apq8064_rtb_device,
+	&apq8064_dcvs_device,
+	&apq8064_msm_gov_device,
+	&apq8064_device_cache_erp,
+	&msm8960_device_ebi1_ch0_erp,
+	&msm8960_device_ebi1_ch1_erp,
+	&epm_adc_device,
+	&coresight_tpiu_device,
+	&coresight_etb_device,
+	&apq8064_coresight_funnel_device,
+	&coresight_etm0_device,
+	&coresight_etm1_device,
+	&coresight_etm2_device,
+	&coresight_etm3_device,
+#ifdef CONFIG_MSM_GEMINI
+	&msm8960_gemini_device,
+#endif
+	&msm_tsens_device,
+	&apq8064_cache_dump_device,
+	&msm_8064_device_tspp,
+#ifdef CONFIG_BATTERY_BCL
+	&battery_bcl_device,
+#endif
+	&apq8064_msm_mpd_device,
+	&apq8064_device_qup_i2c_gsbi1,
+	&apq8064_device_uart_gsbi2,
+	&apq8064_device_uart_gsbi1,
+	&apq8064_device_uart_gsbi4,
+	&msm_device_sps_apq8064,
+#ifdef CONFIG_MSM_ROTATOR
+	&msm_rotator_device,
+#endif
+	&msm8064_pc_cntr,
+};
+
 static struct platform_device *common_i2s_devices[] __initdata = {
 	&apq_cpudai_mi2s,
 	&apq_cpudai_i2s_rx,
@@ -2998,12 +3116,14 @@
 	wmb();
 	iounmap(gsbi_mem);
 	apq8064_i2c_qup_gsbi1_pdata.use_gsbi_shared_mode = 1;
-	apq8064_device_qup_i2c_gsbi3.dev.platform_data =
-					&apq8064_i2c_qup_gsbi3_pdata;
 	apq8064_device_qup_i2c_gsbi1.dev.platform_data =
 					&apq8064_i2c_qup_gsbi1_pdata;
-	apq8064_device_qup_i2c_gsbi4.dev.platform_data =
-					&apq8064_i2c_qup_gsbi4_pdata;
+	if (!machine_is_fsm8064_ep()) {
+		apq8064_device_qup_i2c_gsbi3.dev.platform_data =
+						&apq8064_i2c_qup_gsbi3_pdata;
+		apq8064_device_qup_i2c_gsbi4.dev.platform_data =
+						&apq8064_i2c_qup_gsbi4_pdata;
+	}
 	mpq8064_device_qup_i2c_gsbi5.dev.platform_data =
 					&mpq8064_i2c_qup_gsbi5_pdata;
 }
@@ -3519,6 +3639,8 @@
 		mach_mask = I2C_LIQUID;
 	else if (PLATFORM_IS_MPQ8064())
 		mach_mask = I2C_MPQ_CDP;
+	else if (machine_is_fsm8064_ep())
+		mach_mask = I2C_SURF;
 	else
 		pr_err("unmatched machine ID in register_i2c_devices\n");
 
@@ -3644,9 +3766,11 @@
 					ARRAY_SIZE(pm8917_common_devices));
 	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
 		platform_device_register(&apq8064_device_ext_ts_sw_vreg);
-	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	if (!machine_is_fsm8064_ep())
+		platform_add_devices(common_devices,
+				ARRAY_SIZE(common_devices));
 	if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
-			machine_is_mpq8064_dtv()))
+			machine_is_mpq8064_dtv() || machine_is_fsm8064_ep()))
 		platform_add_devices(common_not_mpq_devices,
 			ARRAY_SIZE(common_not_mpq_devices));
 
@@ -3797,6 +3921,26 @@
 	}
 }
 
+static void __init fsm8064_ep_init(void)
+{
+	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
+		pr_err("meminfo_init() failed!\n");
+
+	apq8064_common_init();
+	ethernet_init();
+	msm_rotator_set_split_iommu_domain();
+	fsm8064_ep_pcie_init();
+	platform_add_devices(ep_devices, ARRAY_SIZE(ep_devices));
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+	apq8064_init_gpu();
+	platform_add_devices(apq8064_footswitch, apq8064_num_footswitch);
+	platform_device_register(&cdp_kp_pdev);
+#ifdef CONFIG_MSM_CAMERA
+	apq8064_init_cam();
+#endif
+	change_memory_power = &apq8064_change_memory_power;
+}
+
 MACHINE_START(APQ8064_CDP, "QCT APQ8064 CDP")
 	.map_io = apq8064_map_io,
 	.reserve = apq8064_reserve,
@@ -3810,6 +3954,18 @@
 	.smp = &msm8960_smp_ops,
 MACHINE_END
 
+MACHINE_START(FSM8064_EP, "QCT FSM8064 EP")
+	.map_io = apq8064_map_io,
+	.reserve = apq8064_reserve,
+	.init_irq = apq8064_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = fsm8064_ep_init,
+	.init_early = apq8064_allocate_memory_regions,
+	.init_very_early = apq8064_early_reserve,
+	.restart = msm_restart,
+MACHINE_END
+
 MACHINE_START(APQ8064_MTP, "QCT APQ8064 MTP")
 	.map_io = apq8064_map_io,
 	.reserve = apq8064_reserve,
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 9cfee09..9b02a5d 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -112,6 +112,8 @@
 			"msm-tsens", NULL),
 	OF_DEV_AUXDATA("qcom,usb-bam-msm", 0xF9A44000, \
 			"usb_bam", NULL),
+	OF_DEV_AUXDATA("qcom,hsic-host", 0xF9A15000, \
+			"msm_hsic_host", NULL),
 	{}
 };
 
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 5b74d44..14f369df 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -3049,22 +3049,30 @@
 	return -ENXIO;
 }
 
-static enum handoff pix_rdi_clk_handoff(struct clk *c)
+static struct clk *pix_rdi_clk_get_parent(struct clk *c)
 {
 	u32 reg;
 	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
+
+	reg = readl_relaxed(rdi->s_reg);
+	rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
+	reg = readl_relaxed(rdi->s2_reg);
+	rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
+
+	return pix_rdi_mux_map[rdi->cur_rate];
+}
+
+static enum handoff pix_rdi_clk_handoff(struct clk *c)
+{
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 	enum handoff ret;
 
 	ret = branch_handoff(&rdi->b, &rdi->c);
 	if (ret == HANDOFF_DISABLED_CLK)
 		return ret;
 
-	reg = readl_relaxed(rdi->s_reg);
-	rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
-	reg = readl_relaxed(rdi->s2_reg);
-	rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
-	c->parent = pix_rdi_mux_map[rdi->cur_rate];
-
+	rdi->prepared = true;
+	rdi->enabled = true;
 	return HANDOFF_ENABLED_CLK;
 }
 
@@ -3078,6 +3086,7 @@
 	.get_rate = pix_rdi_clk_get_rate,
 	.list_rate = pix_rdi_clk_list_rate,
 	.reset = pix_rdi_clk_reset,
+	.get_parent = pix_rdi_clk_get_parent,
 };
 
 static struct pix_rdi_clk csi_pix_clk = {
@@ -5283,8 +5292,10 @@
 	CLK_LOOKUP("core_clk",		gp2_clk.c,		""),
 	CLK_LOOKUP("core_clk",		gsbi1_uart_clk.c, "msm_serial_hsl.1"),
 	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c, "msm_serial_hsl.3"),
 	CLK_LOOKUP("core_clk",		gsbi3_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c, "msm_serial_hsl.4"),
 	CLK_LOOKUP("core_clk",		gsbi5_uart_clk.c, "msm_serial_hsl.2"),
 	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c, "msm_serial_hs.0"),
 	CLK_LOOKUP("core_clk",		gsbi7_uart_clk.c, "msm_serial_hsl.0"),
@@ -5332,6 +5343,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,	"msm_serial_hsl.1"),
 	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,	"qup_i2c.0"),
 	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,	"msm_serial_hsl.3"),
 	CLK_LOOKUP("iface_clk",		gsbi3_p_clk.c,		"qup_i2c.3"),
 	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,		"qup_i2c.4"),
 	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,	"msm_serial_hsl.2"),
@@ -5340,6 +5352,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,	"msm_serial_hs.0"),
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,		"spi_qsd.1"),
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,	"msm_serial_hsl.0"),
+	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,	"msm_serial_hsl.4"),
 	CLK_LOOKUP("ref_clk",	tsif_ref_clk.c,	"msm_tspp.0"),
 	CLK_LOOKUP("iface_clk",		tsif_p_clk.c,		"msm_tspp.0"),
 	CLK_LOOKUP("iface_clk",		usb_fs1_p_clk.c,	""),
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 4432795..a173ba9 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, 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
@@ -598,20 +598,21 @@
 static enum handoff branch_clk_handoff(struct clk *c)
 {
 	struct branch_clk *br = to_branch_clk(c);
-	return branch_handoff(&br->b, &br->c);
+	if (branch_handoff(&br->b, &br->c) == HANDOFF_ENABLED_CLK) {
+		br->enabled = true;
+		return HANDOFF_ENABLED_CLK;
+	}
+
+	return HANDOFF_DISABLED_CLK;
 }
 
-static enum handoff rcg_clk_handoff(struct clk *c)
+static struct clk *rcg_clk_get_parent(struct clk *c)
 {
 	struct rcg_clk *rcg = to_rcg_clk(c);
 	uint32_t ctl_val, ns_val, md_val, ns_mask;
 	struct clk_freq_tbl *freq;
-	enum handoff ret;
 
 	ctl_val = readl_relaxed(rcg->b.ctl_reg);
-	ret = branch_handoff(&rcg->b, &rcg->c);
-	if (ret == HANDOFF_DISABLED_CLK)
-		return HANDOFF_DISABLED_CLK;
 
 	if (rcg->bank_info) {
 		const struct bank_masks *bank_masks = rcg->bank_info;
@@ -628,21 +629,40 @@
 		ns_mask = rcg->ns_mask;
 		md_val = rcg->md_reg ? readl_relaxed(rcg->md_reg) : 0;
 	}
+
 	if (!ns_mask)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
+
 	ns_val = readl_relaxed(rcg->ns_reg) & ns_mask;
 	for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
 		if ((freq->ns_val & ns_mask) == ns_val &&
 		    (!freq->md_val || freq->md_val == md_val))
 			break;
 	}
+
 	if (freq->freq_hz == FREQ_END)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
+	/* Cache the results for the handoff code. */
 	rcg->current_freq = freq;
-	c->parent = freq->src_clk;
-	c->rate = freq->freq_hz;
 
+	return freq->src_clk;
+}
+
+static enum handoff rcg_clk_handoff(struct clk *c)
+{
+	struct rcg_clk *rcg = to_rcg_clk(c);
+	enum handoff ret;
+
+	if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+		c->rate = rcg->current_freq->freq_hz;
+
+	ret = branch_handoff(&rcg->b, &rcg->c);
+	if (ret == HANDOFF_DISABLED_CLK)
+		return HANDOFF_DISABLED_CLK;
+
+	rcg->prepared = true;
+	rcg->enabled = true;
 	return HANDOFF_ENABLED_CLK;
 }
 
@@ -861,6 +881,7 @@
 	.round_rate = rcg_clk_round_rate,
 	.reset = rcg_clk_reset,
 	.set_flags = rcg_clk_set_flags,
+	.get_parent = rcg_clk_get_parent,
 };
 
 static int cdiv_clk_enable(struct clk *c)
@@ -940,6 +961,7 @@
 		reg_val >>= cdiv->div_offset;
 		cdiv->cur_div = (reg_val & (cdiv->max_div - 1)) + 1;
 	}
+	c->rate = cdiv->cur_div;
 
 	return HANDOFF_ENABLED_CLK;
 }
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index cf42355..dd78557 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -69,8 +69,8 @@
 #define MND_MODE_MASK			BM(13, 12)
 #define MND_DUAL_EDGE_MODE_BVAL		BVAL(13, 12, 0x2)
 #define CMD_RCGR_CONFIG_DIRTY_MASK	BM(7, 4)
-#define CBCR_BRANCH_CDIV_MASK		BM(24, 16)
-#define CBCR_BRANCH_CDIV_MASKED(val)	BVAL(24, 16, (val));
+#define CBCR_CDIV_LSB			16
+#define CBCR_CDIV_MSB			24
 
 enum branch_state {
 	BRANCH_ON,
@@ -235,21 +235,17 @@
 	return (rcg->freq_tbl + n)->freq_hz;
 }
 
-static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg, int has_mnd)
+static struct clk *_rcg_clk_get_parent(struct rcg_clk *rcg, int has_mnd)
 {
 	u32 n_regval = 0, m_regval = 0, d_regval = 0;
 	u32 cfg_regval;
 	struct clk_freq_tbl *freq;
 	u32 cmd_rcgr_regval;
 
-	/* Is the root enabled? */
-	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
-	if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
-		return HANDOFF_DISABLED_CLK;
-
 	/* Is there a pending configuration? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
 	if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
 	/* Get values of m, n, d, div and src_sel registers. */
 	if (has_mnd) {
@@ -299,23 +295,45 @@
 
 	/* No known frequency found */
 	if (freq->freq_hz == FREQ_END)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
 	rcg->current_freq = freq;
-	rcg->c.parent = freq->src_clk;
-	rcg->c.rate = freq->freq_hz;
+	return freq->src_clk;
+}
+
+static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg)
+{
+	u32 cmd_rcgr_regval;
+
+	if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+		rcg->c.rate = rcg->current_freq->freq_hz;
+
+	/* Is the root enabled? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
+	if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
+		return HANDOFF_DISABLED_CLK;
 
 	return HANDOFF_ENABLED_CLK;
 }
 
+static struct clk *rcg_mnd_clk_get_parent(struct clk *c)
+{
+	return _rcg_clk_get_parent(to_rcg_clk(c), 1);
+}
+
+static struct clk *rcg_clk_get_parent(struct clk *c)
+{
+	return _rcg_clk_get_parent(to_rcg_clk(c), 0);
+}
+
 static enum handoff rcg_mnd_clk_handoff(struct clk *c)
 {
-	return _rcg_clk_handoff(to_rcg_clk(c), 1);
+	return _rcg_clk_handoff(to_rcg_clk(c));
 }
 
 static enum handoff rcg_clk_handoff(struct clk *c)
 {
-	return _rcg_clk_handoff(to_rcg_clk(c), 0);
+	return _rcg_clk_handoff(to_rcg_clk(c));
 }
 
 #define BRANCH_CHECK_MASK	BM(31, 28)
@@ -412,8 +430,8 @@
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
 	regval = readl_relaxed(CBCR_REG(branch));
-	regval &= ~CBCR_BRANCH_CDIV_MASK;
-	regval |= CBCR_BRANCH_CDIV_MASKED(rate);
+	regval &= ~BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+	regval |= BVAL(CBCR_CDIV_MSB, CBCR_CDIV_LSB, rate);
 	writel_relaxed(regval, CBCR_REG(branch));
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 
@@ -496,9 +514,12 @@
 	if ((cbcr_regval & CBCR_BRANCH_OFF_BIT))
 		return HANDOFF_DISABLED_CLK;
 
-	if (c->parent) {
-		if (c->parent->ops->handoff)
-			return c->parent->ops->handoff(c->parent);
+	if (branch->max_div) {
+		cbcr_regval &= BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+		cbcr_regval >>= CBCR_CDIV_LSB;
+		c->rate = cbcr_regval;
+	} else if (!branch->has_sibling) {
+		c->rate = clk_get_rate(c->parent);
 	}
 
 	return HANDOFF_ENABLED_CLK;
@@ -611,6 +632,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_clk_handoff,
+	.get_parent = rcg_clk_get_parent,
 };
 
 struct clk_ops clk_ops_rcg_mnd = {
@@ -619,6 +641,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_mnd_clk_handoff,
+	.get_parent = rcg_mnd_clk_get_parent,
 };
 
 struct clk_ops clk_ops_branch = {
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 79bc639..aca6494 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -348,6 +348,16 @@
 	return ret;
 }
 
+static enum handoff mdss_dsi_pll_handoff(struct clk *c)
+{
+	/*
+	 * FIXME: Continuous display is not implemented. So the display is
+	 * always off. Implement a poor man's handoff by always returning
+	 * "disabled".
+	 */
+	return HANDOFF_DISABLED_CLK;
+}
+
 void hdmi_pll_disable(void)
 {
 	clk_enable(mdss_dsi_ahb_clk);
@@ -766,6 +776,7 @@
 	.disable = mdss_dsi_pll_disable,
 	.set_rate = mdss_dsi_pll_pixel_set_rate,
 	.round_rate = mdss_dsi_pll_pixel_round_rate,
+	.handoff = mdss_dsi_pll_handoff,
 };
 
 struct clk_ops clk_ops_dsi_byte_pll = {
@@ -773,4 +784,5 @@
 	.disable = mdss_dsi_pll_disable,
 	.set_rate = mdss_dsi_pll_byte_set_rate,
 	.round_rate = mdss_dsi_pll_byte_round_rate,
+	.handoff = mdss_dsi_pll_handoff,
 };
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index a4def28..c1cc27b 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -285,6 +285,18 @@
 	if (rc < 0)
 		return HANDOFF_DISABLED_CLK;
 
+	/*
+	 * Since RPM handoff code may update the software rate of the clock by
+	 * querying the RPM, we need to make sure our request to RPM now
+	 * matches the software rate of the clock. When we send the request
+	 * to RPM, we also need to update any other state info we would
+	 * normally update. So, call the appropriate clock function instead
+	 * of directly using the RPM driver APIs.
+	 */
+	rc = rpm_clk_prepare(clk);
+	if (rc < 0)
+		return HANDOFF_DISABLED_CLK;
+
 	return HANDOFF_ENABLED_CLK;
 }
 
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index 7421ba6..c3145ef 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -139,11 +138,17 @@
 
 static enum handoff voter_clk_handoff(struct clk *clk)
 {
-	/* Apply default rate vote */
-	if (clk->rate)
-		return HANDOFF_ENABLED_CLK;
+	if (!clk->rate)
+		return HANDOFF_DISABLED_CLK;
 
-	return HANDOFF_DISABLED_CLK;
+	/*
+	 * Send the default rate to the parent if necessary and update the
+	 * software state of the voter clock.
+	 */
+	if (voter_clk_prepare(clk) < 0)
+		return HANDOFF_DISABLED_CLK;
+
+	return HANDOFF_ENABLED_CLK;
 }
 
 struct clk_ops clk_ops_voter = {
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index c2bf5ba..e0ee084 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -467,56 +467,83 @@
 }
 EXPORT_SYMBOL(msm_clock_register);
 
-static enum handoff __init __handoff_clk(struct clk *clk)
+static int __init __handoff_clk(struct clk *clk)
 {
-	enum handoff ret;
-	struct handoff_clk *h;
-	unsigned long rate;
-	int err = 0;
+	enum handoff state = HANDOFF_DISABLED_CLK;
+	struct handoff_clk *h = NULL;
+	int rc;
+
+	if (clk == NULL || clk->flags & CLKFLAG_INIT_DONE ||
+	    clk->flags & CLKFLAG_SKIP_HANDOFF)
+		return 0;
+
+	if (clk->flags & CLKFLAG_INIT_ERR)
+		return -ENXIO;
+
+	/* Handoff any 'depends' clock first. */
+	rc = __handoff_clk(clk->depends);
+	if (rc)
+		goto err;
 
 	/*
-	 * Tree roots don't have parents, but need to be handed off. So,
-	 * terminate recursion by returning "enabled". Also return "enabled"
-	 * for clocks with non-zero enable counts since they must have already
-	 * been handed off.
+	 * Handoff functions for the parent must be called before the
+	 * children can be handed off. Without handing off the parents and
+	 * knowing their rate and state (on/off), it's impossible to figure
+	 * out the rate and state of the children.
 	 */
-	if (clk == NULL || clk->count)
-		return HANDOFF_ENABLED_CLK;
+	if (clk->ops->get_parent)
+		clk->parent = clk->ops->get_parent(clk);
 
-	/* Clocks without handoff functions are assumed to be disabled. */
-	if (!clk->ops->handoff || (clk->flags & CLKFLAG_SKIP_HANDOFF))
-		return HANDOFF_DISABLED_CLK;
+	if (IS_ERR(clk->parent)) {
+		rc = PTR_ERR(clk->parent);
+		goto err;
+	}
 
-	/*
-	 * Handoff functions for children must be called before their parents'
-	 * so that the correct parent is available below.
-	 */
-	ret = clk->ops->handoff(clk);
-	if (ret == HANDOFF_ENABLED_CLK) {
-		ret = __handoff_clk(clk->parent);
-		if (ret == HANDOFF_ENABLED_CLK) {
-			h = kmalloc(sizeof(*h), GFP_KERNEL);
-			if (!h) {
-				err = -ENOMEM;
-				goto out;
-			}
-			err = clk_prepare_enable(clk);
-			if (err)
-				goto out;
-			rate = clk_get_rate(clk);
-			if (rate)
-				pr_debug("%s rate=%lu\n", clk->dbg_name, rate);
-			h->clk = clk;
-			list_add_tail(&h->list, &handoff_list);
+	rc = __handoff_clk(clk->parent);
+	if (rc)
+		goto err;
+
+	if (clk->ops->handoff)
+		state = clk->ops->handoff(clk);
+
+	if (state == HANDOFF_ENABLED_CLK) {
+
+		h = kmalloc(sizeof(*h), GFP_KERNEL);
+		if (!h) {
+			rc = -ENOMEM;
+			goto err;
 		}
+
+		rc = clk_prepare_enable(clk->parent);
+		if (rc)
+			goto err;
+
+		rc = clk_prepare_enable(clk->depends);
+		if (rc)
+			goto err_depends;
+
+		rc = vote_rate_vdd(clk, clk->rate);
+		WARN(rc, "%s unable to vote for voltage!\n", clk->dbg_name);
+
+		clk->count = 1;
+		clk->prepare_count = 1;
+		h->clk = clk;
+		list_add_tail(&h->list, &handoff_list);
+
+		pr_debug("Handed off %s rate=%lu\n", clk->dbg_name, clk->rate);
 	}
-out:
-	if (err) {
-		pr_err("%s handoff failed (%d)\n", clk->dbg_name, err);
-		kfree(h);
-		ret = HANDOFF_DISABLED_CLK;
-	}
-	return ret;
+
+	clk->flags |= CLKFLAG_INIT_DONE;
+
+	return 0;
+
+err_depends:
+	clk_disable_unprepare(clk->parent);
+err:
+	kfree(h);
+	clk->flags |= CLKFLAG_INIT_ERR;
+	pr_err("%s handoff failed (%d)\n", clk->dbg_name, rc);
+	return rc;
 }
 
 /**
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index dd2dc1d..056f19e 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -80,8 +80,7 @@
 	cpu_pm_enter();
 #endif
 
-	pm_mode = msm_pm_idle_prepare(dev, drv, index);
-	dev->last_residency = msm_pm_idle_enter(pm_mode);
+	pm_mode = msm_pm_idle_enter(dev, drv, index);
 	for (i = 0; i < dev->state_count; i++) {
 		st_usage = &dev->states_usage[i];
 		if ((enum msm_pm_sleep_mode) cpuidle_get_statedata(st_usage)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index c986064..f87c540 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -24,6 +24,7 @@
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 #include <mach/usbdiag.h>
+#include <mach/msm_serial_hs_lite.h>
 #include <mach/msm_sps.h>
 #include <mach/dma.h>
 #include <mach/msm_dsps.h>
@@ -51,6 +52,7 @@
 
 /* Address of GSBI blocks */
 #define MSM_GSBI1_PHYS		0x12440000
+#define MSM_GSBI2_PHYS		0x12480000
 #define MSM_GSBI3_PHYS		0x16200000
 #define MSM_GSBI4_PHYS		0x16300000
 #define MSM_GSBI5_PHYS		0x1A200000
@@ -59,7 +61,9 @@
 
 /* GSBI UART devices */
 #define MSM_UART1DM_PHYS	(MSM_GSBI1_PHYS + 0x10000)
+#define MSM_UART2DM_PHYS	(MSM_GSBI2_PHYS + 0x10000)
 #define MSM_UART3DM_PHYS	(MSM_GSBI3_PHYS + 0x40000)
+#define MSM_UART4DM_PHYS	(MSM_GSBI4_PHYS + 0x40000)
 #define MSM_UART5DM_PHYS	(MSM_GSBI5_PHYS + 0x40000)
 #define MSM_UART6DM_PHYS	(MSM_GSBI6_PHYS + 0x40000)
 #define MSM_UART7DM_PHYS	(MSM_GSBI7_PHYS + 0x40000)
@@ -203,6 +207,38 @@
 	.resource	= resources_uart_gsbi1,
 };
 
+static struct resource resources_uart_gsbi2[] = {
+	{
+		.start	= APQ8064_GSBI2_UARTDM_IRQ,
+		.end	= APQ8064_GSBI2_UARTDM_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART2DM_PHYS,
+		.end	= MSM_UART2DM_PHYS + PAGE_SIZE - 1,
+		.name	= "uartdm_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MSM_GSBI2_PHYS,
+		.end	= MSM_GSBI2_PHYS + PAGE_SIZE - 1,
+		.name	= "gsbi_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi2_pdata = {
+	.line		= 0,
+};
+
+struct platform_device apq8064_device_uart_gsbi2 = {
+	.name	= "msm_serial_hsl",
+	.id	= 3,
+	.num_resources	= ARRAY_SIZE(resources_uart_gsbi2),
+	.resource	= resources_uart_gsbi2,
+	.dev.platform_data = &uart_gsbi2_pdata,
+};
+
 static struct resource resources_uart_gsbi3[] = {
 	{
 		.start	= GSBI3_UARTDM_IRQ,
@@ -350,6 +386,38 @@
 	.resource	= resources_qup_i2c_gsbi4,
 };
 
+static struct resource resources_uart_gsbi4[] = {
+	{
+		.start	= GSBI4_UARTDM_IRQ,
+		.end	= GSBI4_UARTDM_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART4DM_PHYS,
+		.end	= MSM_UART4DM_PHYS + PAGE_SIZE - 1,
+		.name	= "uartdm_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MSM_GSBI4_PHYS,
+		.end	= MSM_GSBI4_PHYS + PAGE_SIZE - 1,
+		.name	= "gsbi_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi4_pdata = {
+	.line		= 2,
+};
+
+struct platform_device apq8064_device_uart_gsbi4 = {
+	.name	= "msm_serial_hsl",
+	.id	= 4,
+	.num_resources	= ARRAY_SIZE(resources_uart_gsbi4),
+	.resource	= resources_uart_gsbi4,
+	.dev.platform_data = &uart_gsbi4_pdata,
+};
+
 static struct resource resources_qup_spi_gsbi5[] = {
 	{
 		.name   = "spi_base",
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 248af88..8301c29 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -85,7 +85,9 @@
 extern struct platform_device msm8960_device_ebi1_ch1_erp;
 
 extern struct platform_device apq8064_device_uart_gsbi1;
+extern struct platform_device apq8064_device_uart_gsbi2;
 extern struct platform_device apq8064_device_uart_gsbi3;
+extern struct platform_device apq8064_device_uart_gsbi4;
 extern struct platform_device apq8064_device_uart_gsbi7;
 extern struct platform_device apq8064_device_qup_i2c_gsbi1;
 extern struct platform_device apq8064_device_qup_i2c_gsbi3;
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index 0f2feaa..475b483 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -69,7 +69,6 @@
 enum handoff {
 	HANDOFF_ENABLED_CLK,
 	HANDOFF_DISABLED_CLK,
-	HANDOFF_UNKNOWN_RATE,
 };
 
 struct clk_ops {
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
index d69b372..1191bb7 100644
--- a/arch/arm/mach-msm/include/mach/clk.h
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2012-2013 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
@@ -21,6 +21,8 @@
 #define CLKFLAG_SKIP_HANDOFF		0x00000100
 #define CLKFLAG_MIN			0x00000400
 #define CLKFLAG_MAX			0x00000800
+#define CLKFLAG_INIT_DONE		0x00001000
+#define CLKFLAG_INIT_ERR		0x00002000
 
 struct clk_lookup;
 struct clk;
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
index 137d243..2d47e4e 100644
--- a/arch/arm/mach-msm/include/mach/gpio.h
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -16,7 +16,7 @@
 #ifndef __ASM_ARCH_MSM_GPIO_H
 #define __ASM_ARCH_MSM_GPIO_H
 
-#define ARCH_NR_GPIOS 512
+#define ARCH_NR_GPIOS 1024
 
 #include <linux/interrupt.h>
 #include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index e88c4df..9a031b2 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -199,10 +199,13 @@
 	SMEM_SSR_REASON_DSPS0,
 	SMEM_SSR_REASON_VCODEC0,
 	SMEM_SMP2P_APPS_BASE = 427,
-	SMEM_SMP2P_MODEM_BASE = 435,
-	SMEM_SMP2P_AUDIO_BASE = 443,
-	SMEM_SMP2P_WIRLESS_BASE = 451,
-	SMEM_SMP2P_POWER_BASE = 459,
+	SMEM_SMP2P_MODEM_BASE = SMEM_SMP2P_APPS_BASE + 8,    /* 435 */
+	SMEM_SMP2P_AUDIO_BASE = SMEM_SMP2P_MODEM_BASE + 8,   /* 443 */
+	SMEM_SMP2P_WIRLESS_BASE = SMEM_SMP2P_AUDIO_BASE + 8, /* 451 */
+	SMEM_SMP2P_POWER_BASE = SMEM_SMP2P_WIRLESS_BASE + 8, /* 459 */
+	SMEM_FLASH_DEVICE_INFO = SMEM_SMP2P_POWER_BASE + 8,  /* 467 */
+	SMEM_BAM_PIPE_MEMORY,     /* 468 */
+	SMEM_IMAGE_VERSION_TABLE, /* 469 */
 	SMEM_NUM_ITEMS,
 };
 
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index 8c0bf4b..5d1b5e4 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -40,7 +40,7 @@
 
 #define MIN_FRAG_SZ (IPC_ROUTER_HDR_SIZE + sizeof(union rr_control_msg))
 
-#define NUM_SMD_XPRTS 3
+#define NUM_SMD_XPRTS 4
 #define XPRT_NAME_LEN (SMD_MAX_CH_NAME_LEN + 12)
 
 struct msm_ipc_router_smd_xprt {
@@ -76,6 +76,7 @@
 	{"RPCRPY_CNTL", "ipc_rtr_smd_rpcrpy_cntl", SMD_APPS_MODEM, 1},
 	{"IPCRTR", "ipc_rtr_smd_ipcrtr", SMD_APPS_MODEM, 1},
 	{"IPCRTR", "ipc_rtr_q6_ipcrtr", SMD_APPS_QDSP, 1},
+	{"IPCRTR", "ipc_rtr_wcnss_ipcrtr", SMD_APPS_WCNSS, 1},
 };
 
 static struct msm_ipc_router_smd_xprt smd_remote_xprt[NUM_SMD_XPRTS];
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index b6d6965..aa03a6a 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -27,9 +27,11 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/krait-regulator.h>
+#include <linux/debugfs.h>
 #include <mach/msm_iomap.h>
 
 #include "spm.h"
+#include "pm.h"
 
 /*
  *                   supply
@@ -119,6 +121,18 @@
 #define VREF_LDO_BIT_POS	0
 #define VREF_LDO_MASK		KRAIT_MASK(6, 0)
 
+#define LDO_HDROOM_MIN		50000
+#define LDO_HDROOM_MAX		250000
+
+#define LDO_UV_MIN		465000
+#define LDO_UV_MAX		750000
+
+#define LDO_TH_MIN		600000
+#define LDO_TH_MAX		900000
+
+#define LDO_DELTA_MIN		10000
+#define LDO_DELTA_MAX		100000
+
 /**
  * struct pmic_gang_vreg -
  * @name:			the string used to represent the gang
@@ -138,6 +152,8 @@
 	struct list_head	krait_power_vregs;
 	struct mutex		krait_power_vregs_lock;
 	bool			pfm_mode;
+	int			pmic_min_uV_for_retention;
+	bool			retention_enabled;
 };
 
 static struct pmic_gang_vreg *the_gang;
@@ -162,11 +178,21 @@
 	int				retention_uV;
 	int				headroom_uV;
 	int				ldo_threshold_uV;
+	int				ldo_delta_uV;
 	bool				online;
 };
 
 static u32 version;
 
+static int is_between(int left, int right, int value)
+{
+	if (left >= right && left >= value && value >= right)
+		return 1;
+	if (left <= right && left <= value && value <= right)
+		return 1;
+	return 0;
+}
+
 static void krait_masked_write(struct krait_power_vreg *kvreg,
 					int reg, uint32_t mask, uint32_t val)
 {
@@ -185,6 +211,23 @@
 	mb();
 }
 
+static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
+{
+	uint32_t reg_val;
+	int uV;
+
+	reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
+	reg_val &= VREF_RET_MASK;
+	reg_val >>= VREF_RET_POS;
+
+	if (reg_val == 0)
+		uV = 0;
+	else
+		uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
+
+	return uV;
+}
+
 static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
 {
 	uint32_t reg_val;
@@ -260,7 +303,8 @@
 
 static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
 {
-	if (kvreg->mode == LDO_MODE && get_krait_ldo_uv(kvreg) == kvreg->uV)
+	if (kvreg->mode == LDO_MODE
+		&& get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
 		return 0;
 
 	/*
@@ -270,7 +314,7 @@
 	if (kvreg->mode == LDO_MODE)
 		switch_to_using_hs(kvreg);
 
-	set_krait_ldo_uv(kvreg, kvreg->uV);
+	set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
 
 	/*
 	 * enable ldo - note that both LDO and BHS are are supplying voltage to
@@ -328,6 +372,22 @@
 		uV = PMIC_VOLTAGE_MAX;
 	}
 
+	if (uV < pvreg->pmic_min_uV_for_retention) {
+		if (pvreg->retention_enabled) {
+			pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+					uV, pvreg->pmic_min_uV_for_retention);
+			msm_pm_enable_retention(false);
+			pvreg->retention_enabled = false;
+		}
+	} else {
+		if (!pvreg->retention_enabled) {
+			pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+					uV, pvreg->pmic_min_uV_for_retention);
+			msm_pm_enable_retention(true);
+			pvreg->retention_enabled = true;
+		}
+	}
+
 	setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
 
 	rc = msm_spm_apcs_set_vdd(setpoint);
@@ -349,18 +409,19 @@
 	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
 		if (!kvreg->online)
 			continue;
-		if (kvreg->uV > kvreg->ldo_threshold_uV
-			 || kvreg->uV > vmax - kvreg->headroom_uV) {
-			rc = switch_to_using_hs(kvreg);
+		if (kvreg->uV <= kvreg->ldo_threshold_uV
+			&& kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
+				<= vmax) {
+			rc = switch_to_using_ldo(kvreg);
 			if (rc < 0) {
-				pr_err("could not switch %s to hs rc = %d\n",
+				pr_err("could not switch %s to ldo rc = %d\n",
 							kvreg->name, rc);
 				return rc;
 			}
 		} else {
-			rc = switch_to_using_ldo(kvreg);
+			rc = switch_to_using_hs(kvreg);
 			if (rc < 0) {
-				pr_err("could not switch %s to ldo rc = %d\n",
+				pr_err("could not switch %s to hs rc = %d\n",
 							kvreg->name, rc);
 				return rc;
 			}
@@ -482,6 +543,8 @@
 	pvreg->name = "pmic_gang";
 	pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
 	pvreg->pmic_phase_count = 1;
+	pvreg->retention_enabled = true;
+	pvreg->pmic_min_uV_for_retention = INT_MAX;
 
 	mutex_init(&pvreg->krait_power_vregs_lock);
 	INIT_LIST_HEAD(&pvreg->krait_power_vregs);
@@ -740,6 +803,43 @@
 	.is_enabled		= krait_power_is_enabled,
 };
 
+static struct dentry *dent;
+static int get_retention_dbg_uV(void *data, u64 *val)
+{
+	struct pmic_gang_vreg *pvreg = data;
+	struct krait_power_vreg *kvreg;
+
+	mutex_lock(&pvreg->krait_power_vregs_lock);
+	if (!list_empty(&pvreg->krait_power_vregs)) {
+		/* return the retention voltage on just the first cpu */
+		kvreg = list_entry((&pvreg->krait_power_vregs)->next,
+			typeof(*kvreg), link);
+		*val = get_krait_retention_ldo_uv(kvreg);
+	}
+	mutex_unlock(&pvreg->krait_power_vregs_lock);
+	return 0;
+}
+
+static int set_retention_dbg_uV(void *data, u64 val)
+{
+	struct pmic_gang_vreg *pvreg = data;
+	struct krait_power_vreg *kvreg;
+	int retention_uV = val;
+
+	if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
+		return -EINVAL;
+
+	mutex_lock(&pvreg->krait_power_vregs_lock);
+	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+		kvreg->retention_uV = retention_uV;
+		set_krait_retention_uv(kvreg, retention_uV);
+	}
+	mutex_unlock(&pvreg->krait_power_vregs_lock);
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
+			get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
+
 static void kvreg_hw_init(struct krait_power_vreg *kvreg)
 {
 	/*
@@ -765,24 +865,6 @@
 	pr_debug("version= 0x%x\n", version);
 }
 
-static int is_between(int left, int right, int value)
-{
-	if (left >= right && left >= value && value >= right)
-		return 1;
-	if (left <= right && left <= value && value <= right)
-		return 1;
-	return 0;
-}
-
-#define LDO_HDROOM_MIN		50000
-#define LDO_HDROOM_MAX		250000
-
-#define LDO_UV_MIN		465000
-#define LDO_UV_MAX		750000
-
-#define LDO_TH_MIN		600000
-#define LDO_TH_MAX		800000
-
 static int __devinit krait_power_probe(struct platform_device *pdev)
 {
 	struct krait_power_vreg *kvreg;
@@ -790,6 +872,7 @@
 	struct regulator_init_data *init_data = pdev->dev.platform_data;
 	int rc = 0;
 	int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
+	int ldo_delta_uV;
 
 	/* Initialize the pmic gang if it hasn't been initialized already */
 	if (the_gang == NULL) {
@@ -803,6 +886,12 @@
 		glb_init(pdev);
 	}
 
+	if (dent == NULL) {
+		dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
+		debugfs_create_file("retention_uV",
+				0644, dent, the_gang, &retention_fops);
+	}
+
 	if (pdev->dev.of_node) {
 		/* Get init_data from device tree. */
 		init_data = of_get_regulator_init_data(&pdev->dev,
@@ -865,6 +954,19 @@
 					ldo_threshold_uV);
 			return -EINVAL;
 		}
+
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,ldo-delta-voltage",
+					&ldo_delta_uV);
+		if (rc < 0) {
+			pr_err("ldo-delta-voltage missing rc=%d\n", rc);
+			return rc;
+		}
+		if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
+			pr_err("bad ldo-delta-voltage = %d specified\n",
+					ldo_delta_uV);
+			return -EINVAL;
+		}
 	}
 
 	if (!init_data) {
@@ -916,10 +1018,14 @@
 	kvreg->retention_uV	= retention_uV;
 	kvreg->ldo_default_uV	= ldo_default_uV;
 	kvreg->ldo_threshold_uV = ldo_threshold_uV;
+	kvreg->ldo_delta_uV	= ldo_delta_uV;
 
 	platform_set_drvdata(pdev, kvreg);
 
 	mutex_lock(&the_gang->krait_power_vregs_lock);
+	the_gang->pmic_min_uV_for_retention
+		= min(the_gang->pmic_min_uV_for_retention,
+			kvreg->retention_uV + kvreg->headroom_uV);
 	list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
 	mutex_unlock(&the_gang->krait_power_vregs_lock);
 
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 463f2a5..fcb4299 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -57,8 +57,6 @@
 		bool from_idle, bool notify_rpm)
 {
 	int ret = 0;
-	int debug_mask;
-	struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
 	struct msm_lpm_sleep_data sleep_data;
 
 	sleep_data.limits = limits;
@@ -66,28 +64,34 @@
 	atomic_notifier_call_chain(&__get_cpu_var(lpm_notify_head),
 		MSM_LPM_STATE_ENTER, &sleep_data);
 
-	ret = msm_rpm_enter_sleep();
-	if (ret) {
-		pr_warn("%s(): RPM failed to enter sleep err:%d\n",
-				__func__, ret);
-		goto bail;
+	if (notify_rpm) {
+		int debug_mask;
+		struct msm_rpmrs_limits *l = (struct msm_rpmrs_limits *)limits;
+
+		ret = msm_rpm_enter_sleep();
+		if (ret) {
+			pr_warn("%s(): RPM failed to enter sleep err:%d\n",
+					__func__, ret);
+			goto bail;
+		}
+		if (from_idle)
+			debug_mask = msm_lpm_lvl_dbg_msk &
+					MSM_LPM_LVL_DBG_IDLE_LIMITS;
+		else
+			debug_mask = msm_lpm_lvl_dbg_msk &
+					MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
+
+		if (debug_mask)
+			pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
+					__func__, l->pxo, l->l2_cache,
+					l->vdd_mem_lower_bound,
+					l->vdd_mem_upper_bound,
+					l->vdd_dig_lower_bound,
+					l->vdd_dig_upper_bound);
+
+		ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle,
+				notify_rpm);
 	}
-	if (from_idle)
-		debug_mask = msm_lpm_lvl_dbg_msk &
-				MSM_LPM_LVL_DBG_IDLE_LIMITS;
-	else
-		debug_mask = msm_lpm_lvl_dbg_msk &
-				MSM_LPM_LVL_DBG_SUSPEND_LIMITS;
-
-	if (debug_mask)
-		pr_info("%s(): pxo:%d l2:%d mem:0x%x(0x%x) dig:0x%x(0x%x)\n",
-				__func__, l->pxo, l->l2_cache,
-				l->vdd_mem_lower_bound,
-				l->vdd_mem_upper_bound,
-				l->vdd_dig_lower_bound,
-				l->vdd_dig_upper_bound);
-
-	ret = msm_lpmrs_enter_sleep(sclk_count, l, from_idle, notify_rpm);
 bail:
 	return ret;
 }
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index ea17efe..d416c19 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -1932,17 +1932,18 @@
 	}
 
 	for (i = 0; i < info->node_info->num_mports; i++) {
-		/* If in bypass mode, update priority */
-		if (info->node_info->mode != BIMC_QOS_MODE_BYPASS)
+		/* If not in bypass mode, update priority */
+		if (info->node_info->mode != BIMC_QOS_MODE_BYPASS) {
 			msm_bus_bimc_set_qos_prio(binfo, info->node_info->
 				qport[i], info->node_info->mode, qmode);
 
-		/* If in fixed mode, update bandwidth */
-		if (info->node_info->mode != BIMC_QOS_MODE_FIXED) {
-			struct msm_bus_bimc_qos_bw qbw;
-			qbw.ws = info->node_info->ws;
-			msm_bus_bimc_set_qos_bw(binfo,
-				info->node_info->qport[i], &qbw);
+			/* If not in fixed mode, update bandwidth */
+			if (info->node_info->mode != BIMC_QOS_MODE_FIXED) {
+				struct msm_bus_bimc_qos_bw qbw;
+				qbw.ws = info->node_info->ws;
+				msm_bus_bimc_set_qos_bw(binfo,
+					info->node_info->qport[i], &qbw);
+			}
 		}
 
 		/* set mode */
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
index 88fab96..7c2b4c9 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_rpm_smd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -101,7 +101,7 @@
 		if (ret) {
 			MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n",
 				rsc_type);
-			return ret;
+			goto free_rpm_request;
 		}
 
 		MSM_BUS_DBG("Added Key: %d, Val: %llu, size: %d\n", key,
@@ -112,22 +112,26 @@
 		if (ret) {
 			MSM_BUS_WARN("RPM: Add KVP failed for RPM Req:%u\n",
 				rsc_type);
-			return ret;
+			goto free_rpm_request;
 		}
 	}
 
 	msg_id = msm_rpm_send_request(rpm_req);
 	if (!msg_id) {
 		MSM_BUS_WARN("RPM: No message ID for req\n");
-		return -ENXIO;
+		ret = -ENXIO;
+		goto free_rpm_request;
 	}
 
 	ret = msm_rpm_wait_for_ack(msg_id);
 	if (ret) {
 		MSM_BUS_WARN("RPM: Ack failed\n");
-		return ret;
+		goto free_rpm_request;
 	}
 
+free_rpm_request:
+	msm_rpm_free_request(rpm_req);
+
 	return ret;
 }
 
diff --git a/arch/arm/mach-msm/msm_watchdog_v2.c b/arch/arm/mach-msm/msm_watchdog_v2.c
index 6aa14a6..ef10cdc 100644
--- a/arch/arm/mach-msm/msm_watchdog_v2.c
+++ b/arch/arm/mach-msm/msm_watchdog_v2.c
@@ -333,7 +333,14 @@
 		wdog_dd->last_pet, nanosec_rem / 1000);
 	if (wdog_dd->do_ipi_ping)
 		dump_cpu_alive_mask(wdog_dd);
-	panic("Apps watchdog bark received!");
+	printk(KERN_INFO "Causing a watchdog bite!");
+	__raw_writel(1, wdog_dd->base + WDT0_BITE_TIME);
+	mb();
+	__raw_writel(1, wdog_dd->base + WDT0_RST);
+	mb();
+	/* Delay to make sure bite occurs */
+	mdelay(1);
+	panic("Failed to cause a watchdog bite! - Falling back to kernel panic!");
 	return IRQ_HANDLED;
 }
 
diff --git a/arch/arm/mach-msm/no-pm.c b/arch/arm/mach-msm/no-pm.c
index 0db6e68..a8d4fdb 100644
--- a/arch/arm/mach-msm/no-pm.c
+++ b/arch/arm/mach-msm/no-pm.c
@@ -37,15 +37,11 @@
 
 void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls) {}
 
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv, int index)
 {
 	return -ENOSYS;
 }
 
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
-{
-	return -ENOSYS;
-}
-
 void msm_pm_enable_retention(bool enable) {}
+
diff --git a/arch/arm/mach-msm/perf_debug.c b/arch/arm/mach-msm/perf_debug.c
new file mode 100644
index 0000000..52e58a2
--- /dev/null
+++ b/arch/arm/mach-msm/perf_debug.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 2013, 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.
+ */
+
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+
+/*
+ * Subsequent patches should add an entry to end of this string.
+ * Format is incrementing sequence number followed by text of
+ * patch commit title with newline.
+ * Note trailing ';' is on its own line to simplify addition of
+ * future strings.
+ */
+static char *descriptions =
+	"0  msm: perf: add debug patch logging framework\n"
+;
+
+static ssize_t desc_read(struct file *fp, char __user *buf,
+			 size_t count, loff_t *pos)
+{
+	return simple_read_from_buffer(buf, count, pos, descriptions,
+				       strlen(descriptions));
+}
+
+static const struct file_operations perf_debug_desc_fops = {
+	.read = desc_read,
+};
+
+static int msm_perf_debugfs_init(void)
+{
+	int ret = 0;
+	struct dentry *dir;
+	struct dentry *file;
+
+	dir = debugfs_create_dir("msm-perf-patches", NULL);
+	if (IS_ERR_OR_NULL(dir)) {
+		pr_err("failed to create msm-perf-patches dir in debugfs\n");
+		ret = PTR_ERR(dir);
+		goto init_exit;
+	}
+
+	file = debugfs_create_file("descriptions", 0444, dir, NULL,
+				   &perf_debug_desc_fops);
+	if (IS_ERR_OR_NULL(file)) {
+		debugfs_remove(dir);
+		pr_err("failed to create descriptions file for msm-perf-patches\n");
+		ret = PTR_ERR(file);
+		goto init_exit;
+	}
+
+init_exit:
+	return ret;
+}
+late_initcall(msm_perf_debugfs_init);
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 261d433..af6f8af 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -475,8 +475,6 @@
 	}
 }
 
-static void *msm_pm_idle_rs_limits;
-
 static void msm_pm_swfi(void)
 {
 	msm_pm_config_hw_before_swfi();
@@ -775,8 +773,9 @@
 	}
 }
 
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
-		struct cpuidle_driver *drv, int index)
+static int msm_pm_idle_prepare(struct cpuidle_device *dev,
+		struct cpuidle_driver *drv, int index,
+		void **msm_pm_idle_rs_limits)
 {
 	int i;
 	unsigned int power_usage = -1;
@@ -803,7 +802,6 @@
 		struct cpuidle_state_usage *st_usage = &dev->states_usage[i];
 		enum msm_pm_sleep_mode mode;
 		bool allow;
-		void *rs_limits = NULL;
 		uint32_t power;
 		int idx;
 
@@ -850,17 +848,20 @@
 			/* fall through */
 
 			if (pm_sleep_ops.lowest_limits)
-				rs_limits = pm_sleep_ops.lowest_limits(true,
-						mode, &time_param, &power);
+				*msm_pm_idle_rs_limits =
+					pm_sleep_ops.lowest_limits(
+						true, mode,
+						&time_param, &power);
 
 			if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
 				pr_info("CPU%u: %s: %s, latency %uus, "
 					"sleep %uus, limit %p\n",
 					dev->cpu, __func__, state->desc,
 					time_param.latency_us,
-					time_param.sleep_us, rs_limits);
+					time_param.sleep_us,
+					*msm_pm_idle_rs_limits);
 
-			if (!rs_limits)
+			if (!*msm_pm_idle_rs_limits)
 				allow = false;
 			break;
 
@@ -880,8 +881,6 @@
 				ret = mode;
 			}
 
-			if (MSM_PM_SLEEP_MODE_POWER_COLLAPSE == mode)
-				msm_pm_idle_rs_limits = rs_limits;
 		}
 	}
 
@@ -895,11 +894,27 @@
 	return ret;
 }
 
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode)
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
+	struct cpuidle_driver *drv, int index)
 {
 	int64_t time;
-	int exit_stat;
 	bool collapsed = 1;
+	int exit_stat = -1;
+	enum msm_pm_sleep_mode sleep_mode;
+	void *msm_pm_idle_rs_limits = NULL;
+	int sleep_delay = 1;
+	int ret = -ENODEV;
+	int64_t timer_expiration = 0;
+	int notify_rpm = false;
+	bool timer_halted = false;
+
+	sleep_mode = msm_pm_idle_prepare(dev, drv, index,
+		&msm_pm_idle_rs_limits);
+
+	if (!msm_pm_idle_rs_limits) {
+		sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
+		goto cpuidle_enter_bail;
+	}
 
 	if (MSM_PM_DEBUG_IDLE & msm_pm_debug_mask)
 		pr_info("CPU%u: %s: mode %d\n",
@@ -907,76 +922,80 @@
 
 	time = ktime_to_ns(ktime_get());
 
-	switch (sleep_mode) {
-	case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
-		msm_pm_swfi();
-		exit_stat = MSM_PM_STAT_IDLE_WFI;
-		break;
-
-	case MSM_PM_SLEEP_MODE_RETENTION:
-		msm_pm_retention();
-		exit_stat = MSM_PM_STAT_RETENTION;
-		break;
-
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
-		collapsed = msm_pm_power_collapse_standalone(true);
-		exit_stat = MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
-		break;
-
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE: {
-		int64_t timer_expiration = 0;
-		bool timer_halted = false;
-		uint32_t sleep_delay;
-		int ret = -ENODEV;
-		int notify_rpm =
-			(sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE);
+	if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
+		notify_rpm = true;
 		timer_expiration = msm_pm_timer_enter_idle();
 
 		sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
 			timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
 		if (sleep_delay == 0) /* 0 would mean infinite time */
 			sleep_delay = 1;
+	}
 
-		if (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask)
-			clock_debug_print_enabled();
+	if (pm_sleep_ops.enter_sleep)
+		ret = pm_sleep_ops.enter_sleep(sleep_delay,
+			msm_pm_idle_rs_limits,
+			true, notify_rpm);
+	if (!ret) {
 
-		if (pm_sleep_ops.enter_sleep)
-			ret = pm_sleep_ops.enter_sleep(sleep_delay,
-					msm_pm_idle_rs_limits,
-					true, notify_rpm);
-		if (!ret) {
+		switch (sleep_mode) {
+		case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
+			msm_pm_swfi();
+			exit_stat = MSM_PM_STAT_IDLE_WFI;
+			break;
+
+		case MSM_PM_SLEEP_MODE_RETENTION:
+			msm_pm_retention();
+			exit_stat = MSM_PM_STAT_RETENTION;
+			break;
+
+		case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
+			collapsed = msm_pm_power_collapse_standalone(true);
+			exit_stat = MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE;
+			break;
+
+		case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
+			if (MSM_PM_DEBUG_IDLE_CLK & msm_pm_debug_mask)
+				clock_debug_print_enabled();
+
 			collapsed = msm_pm_power_collapse(true);
 			timer_halted = true;
 
-			if (pm_sleep_ops.exit_sleep)
-				pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits,
-						true, notify_rpm, collapsed);
+			exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
+			msm_pm_timer_exit_idle(timer_halted);
+			break;
+
+		case MSM_PM_SLEEP_MODE_NOT_SELECTED:
+			goto cpuidle_enter_bail;
+			break;
+
+		default:
+			__WARN();
+			goto cpuidle_enter_bail;
+			break;
 		}
+		if (pm_sleep_ops.exit_sleep)
+			pm_sleep_ops.exit_sleep(msm_pm_idle_rs_limits,
+					true, notify_rpm, collapsed);
+
+		time = ktime_to_ns(ktime_get()) - time;
+		msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode,
+					collapsed);
+		if (exit_stat >= 0)
+			msm_pm_add_stat(exit_stat, time);
+		do_div(time, 1000);
+		dev->last_residency = (int) time;
+		return sleep_mode;
+
+	} else if (sleep_mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) {
 		msm_pm_timer_exit_idle(timer_halted);
-		exit_stat = MSM_PM_STAT_IDLE_POWER_COLLAPSE;
-		break;
-	}
-
-	case MSM_PM_SLEEP_MODE_NOT_SELECTED:
-		goto cpuidle_enter_bail;
-		break;
-
-	default:
-		__WARN();
-		goto cpuidle_enter_bail;
-		break;
-	}
-
-	time = ktime_to_ns(ktime_get()) - time;
-	msm_pm_add_stat(exit_stat, time);
-	msm_pm_ftrace_lpm_exit(smp_processor_id(), sleep_mode,
-				collapsed);
-
-	do_div(time, 1000);
-	return (int) time;
+		sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
+	} else
+		sleep_mode = MSM_PM_SLEEP_MODE_NOT_SELECTED;
 
 cpuidle_enter_bail:
-	return 0;
+	dev->last_residency = 0;
+	return sleep_mode;
 }
 
 void msm_pm_cpu_enter_lowpower(unsigned int cpu)
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 399194a..43bb7de 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -108,10 +108,9 @@
 };
 
 void msm_pm_set_platform_data(struct msm_pm_platform_data *data, int count);
-int msm_pm_idle_prepare(struct cpuidle_device *dev,
+enum msm_pm_sleep_mode msm_pm_idle_enter(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv, int index);
 void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls);
-int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode);
 void msm_pm_cpu_enter_lowpower(unsigned int cpu);
 void __init msm_pm_set_tz_retention_flag(unsigned int flag);
 void msm_pm_enable_retention(bool enable);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 67ef0ad..fc0de3b 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1030,7 +1030,7 @@
 	return 0;
 }
 
-static void audio_aio_ioport_reset(struct q6audio_aio *audio)
+void audio_aio_ioport_reset(struct q6audio_aio *audio)
 {
 	if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
 		/* If fsync is in progress, make sure
@@ -1204,15 +1204,15 @@
 				audio, audio->ac->session);
 		mutex_lock(&audio->lock);
 		audio->stopped = 1;
-		audio_aio_flush(audio);
-		audio->enabled = 0;
-		audio->drv_status &= ~ADRV_STATUS_PAUSE;
+		rc = audio_aio_flush(audio);
 		if (rc < 0) {
 			pr_err("%s[%p]:Audio Stop procedure failed rc=%d\n",
 				__func__, audio, rc);
 			mutex_unlock(&audio->lock);
 			break;
 		}
+		audio->enabled = 0;
+		audio->drv_status &= ~ADRV_STATUS_PAUSE;
 		if (audio->drv_status & ADRV_STATUS_FSYNC) {
 			pr_debug("%s[%p] Waking up the audio_aio_fsync\n",
 					__func__, audio);
@@ -1261,8 +1261,6 @@
 		}
 		/* Flush DSP */
 		rc = audio_aio_flush(audio);
-		/* Flush input / Output buffer in software*/
-		audio_aio_ioport_reset(audio);
 		if (rc < 0) {
 			pr_err("%s[%p]:AUDIO_FLUSH interrupted\n",
 				__func__, audio);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
index d518254..81232ad 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.h
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -212,6 +212,7 @@
 int audio_aio_fsync(struct file *file, loff_t start, loff_t end, int datasync);
 void audio_aio_async_out_flush(struct q6audio_aio *audio);
 void audio_aio_async_in_flush(struct q6audio_aio *audio);
+void audio_aio_ioport_reset(struct q6audio_aio *audio);
 #ifdef CONFIG_DEBUG_FS
 ssize_t audio_aio_debug_open(struct inode *inode, struct file *file);
 ssize_t audio_aio_debug_read(struct file *file, char __user *buf,
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
index 96f823f..3fe9e95 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v1_aio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013 Code Aurora Forum. 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
@@ -39,6 +39,9 @@
 	case ASM_DATA_EVENT_ENC_SR_CM_NOTIFY:
 		audio_aio_cb(opcode, token, payload, audio);
 		break;
+	case APR_BASIC_RSP_RESULT:
+		audio_aio_cb(opcode, token, payload, audio);
+		break;
 	default:
 		pr_debug("%s:Unhandled event = 0x%8x\n", __func__, opcode);
 		break;
@@ -106,6 +109,26 @@
 		e_payload.stream_info.sample_rate = audio->pcm_cfg.sample_rate;
 		audio_aio_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload);
 		break;
+	case APR_BASIC_RSP_RESULT:
+		switch (payload[0]) {
+		case ASM_STREAM_CMD_FLUSH:
+			if (payload[1] == ADSP_EOK) {
+				pr_debug("%s: FLUSH CMD success\n", __func__);
+				audio_aio_ioport_reset(audio);
+				audio->wflush = 0;
+				audio->rflush = 0;
+			} else {
+				pr_err("%s: FLUSH CMD failed with status:%d\n",
+					__func__, payload[1]);
+				audio_aio_ioport_reset(audio);
+				audio->wflush = 0;
+				audio->rflush = 0;
+			}
+			break;
+		default:
+			pr_debug("%s: cmd%x cmd_status:%d\n",
+				__func__, payload[0], payload[1]);
+		}
 	default:
 		break;
 	}
diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c
index 1f6bd1d..e734ece 100644
--- a/drivers/coresight/coresight-csr.c
+++ b/drivers/coresight/coresight-csr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 #include <linux/of_coresight.h>
 #include <linux/coresight.h>
 
@@ -74,6 +75,7 @@
 	void __iomem		*base;
 	struct device		*dev;
 	struct coresight_device	*csdev;
+	uint32_t		blksize;
 };
 
 static struct csr_drvdata *csrdrvdata;
@@ -86,7 +88,7 @@
 	CSR_UNLOCK(drvdata);
 
 	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
-	usbbamctrl = (usbbamctrl & ~0x3) | BLKSIZE_2048;
+	usbbamctrl = (usbbamctrl & ~0x3) | drvdata->blksize;
 	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);
 
 	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
@@ -119,6 +121,7 @@
 
 static int __devinit csr_probe(struct platform_device *pdev)
 {
+	int ret;
 	struct device *dev = &pdev->dev;
 	struct coresight_platform_data *pdata;
 	struct csr_drvdata *drvdata;
@@ -148,6 +151,13 @@
 	if (!drvdata->base)
 		return -ENOMEM;
 
+	if (pdev->dev.of_node) {
+		ret = of_property_read_u32(pdev->dev.of_node, "qcom,blk-size",
+					   &drvdata->blksize);
+		if (ret)
+			drvdata->blksize = BLKSIZE_256;
+	}
+
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
 		return -ENOMEM;
diff --git a/drivers/crypto/msm/qcryptohw_50.h b/drivers/crypto/msm/qcryptohw_50.h
index d77311d..0fb924f 100644
--- a/drivers/crypto/msm/qcryptohw_50.h
+++ b/drivers/crypto/msm/qcryptohw_50.h
@@ -59,77 +59,78 @@
 #define CRYPTO_ENCR_XTS_KEY6_REG		0x1D038
 #define CRYPTO_ENCR_XTS_KEY7_REG		0x1D03C
 
-#define CRYPTO_ENCR_PIP0_KEY0_REG		0x1E000
-#define CRYPTO_ENCR_PIP0_KEY1_REG		0x1E004
-#define CRYPTO_ENCR_PIP0_KEY2_REG		0x1E008
-#define CRYPTO_ENCR_PIP0_KEY3_REG		0x1E00C
-#define CRYPTO_ENCR_PIP0_KEY4_REG		0x1E010
-#define CRYPTO_ENCR_PIP0_KEY5_REG		0x1E004
-#define CRYPTO_ENCR_PIP0_KEY6_REG		0x1E008
-#define CRYPTO_ENCR_PIP0_KEY7_REG		0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY0_REG		0x1E000
+#define CRYPTO_ENCR_PIPE0_KEY1_REG		0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY2_REG		0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY3_REG		0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY4_REG		0x1E010
+#define CRYPTO_ENCR_PIPE0_KEY5_REG		0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY6_REG		0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY7_REG		0x1E00C
 
-#define CRYPTO_ENCR_PIP1_KEY0_REG		0x1E000
-#define CRYPTO_ENCR_PIP1_KEY1_REG		0x1E004
-#define CRYPTO_ENCR_PIP1_KEY2_REG		0x1E008
-#define CRYPTO_ENCR_PIP1_KEY3_REG		0x1E00C
-#define CRYPTO_ENCR_PIP1_KEY4_REG		0x1E010
-#define CRYPTO_ENCR_PIP1_KEY5_REG		0x1E014
-#define CRYPTO_ENCR_PIP1_KEY6_REG		0x1E018
-#define CRYPTO_ENCR_PIP1_KEY7_REG		0x1E01C
+#define CRYPTO_ENCR_PIPE1_KEY0_REG		0x1E020
+#define CRYPTO_ENCR_PIPE1_KEY1_REG		0x1E024
+#define CRYPTO_ENCR_PIPE1_KEY2_REG		0x1E028
+#define CRYPTO_ENCR_PIPE1_KEY3_REG		0x1E02C
+#define CRYPTO_ENCR_PIPE1_KEY4_REG		0x1E030
+#define CRYPTO_ENCR_PIPE1_KEY5_REG		0x1E034
+#define CRYPTO_ENCR_PIPE1_KEY6_REG		0x1E038
+#define CRYPTO_ENCR_PIPE1_KEY7_REG		0x1E03C
 
-#define CRYPTO_ENCR_PIP2_KEY0_REG		0x1E020
-#define CRYPTO_ENCR_PIP2_KEY1_REG		0x1E024
-#define CRYPTO_ENCR_PIP2_KEY2_REG		0x1E028
-#define CRYPTO_ENCR_PIP2_KEY3_REG		0x1E02C
-#define CRYPTO_ENCR_PIP2_KEY4_REG		0x1E030
-#define CRYPTO_ENCR_PIP2_KEY5_REG		0x1E034
-#define CRYPTO_ENCR_PIP2_KEY6_REG		0x1E038
-#define CRYPTO_ENCR_PIP2_KEY7_REG		0x1E03C
+#define CRYPTO_ENCR_PIPE2_KEY0_REG		0x1E040
+#define CRYPTO_ENCR_PIPE2_KEY1_REG		0x1E044
+#define CRYPTO_ENCR_PIPE2_KEY2_REG		0x1E048
+#define CRYPTO_ENCR_PIPE2_KEY3_REG		0x1E04C
+#define CRYPTO_ENCR_PIPE2_KEY4_REG		0x1E050
+#define CRYPTO_ENCR_PIPE2_KEY5_REG		0x1E054
+#define CRYPTO_ENCR_PIPE2_KEY6_REG		0x1E058
+#define CRYPTO_ENCR_PIPE2_KEY7_REG		0x1E05C
 
-#define CRYPTO_ENCR_PIP3_KEY0_REG		0x1E040
-#define CRYPTO_ENCR_PIP3_KEY1_REG		0x1E044
-#define CRYPTO_ENCR_PIP3_KEY2_REG		0x1E048
-#define CRYPTO_ENCR_PIP3_KEY3_REG		0x1E04C
-#define CRYPTO_ENCR_PIP3_KEY4_REG		0x1E050
-#define CRYPTO_ENCR_PIP3_KEY5_REG		0x1E054
-#define CRYPTO_ENCR_PIP3_KEY6_REG		0x1E058
-#define CRYPTO_ENCR_PIP3_KEY7_REG		0x1E05C
+#define CRYPTO_ENCR_PIPE3_KEY0_REG		0x1E060
+#define CRYPTO_ENCR_PIPE3_KEY1_REG		0x1E064
+#define CRYPTO_ENCR_PIPE3_KEY2_REG		0x1E068
+#define CRYPTO_ENCR_PIPE3_KEY3_REG		0x1E06C
+#define CRYPTO_ENCR_PIPE3_KEY4_REG		0x1E070
+#define CRYPTO_ENCR_PIPE3_KEY5_REG		0x1E074
+#define CRYPTO_ENCR_PIPE3_KEY6_REG		0x1E078
+#define CRYPTO_ENCR_PIPE3_KEY7_REG		0x1E07C
 
-#define CRYPTO_ENCR_PIP0_XTS_KEY0_REG		0x1E200
-#define CRYPTO_ENCR_PIP0_XTS_KEY1_REG		0x1E204
-#define CRYPTO_ENCR_PIP0_XTS_KEY2_REG		0x1E208
-#define CRYPTO_ENCR_PIP0_XTS_KEY3_REG		0x1E20C
-#define CRYPTO_ENCR_PIP0_XTS_KEY4_REG		0x1E210
-#define CRYPTO_ENCR_PIP0_XTS_KEY5_REG		0x1E214
-#define CRYPTO_ENCR_PIP0_XTS_KEY6_REG		0x1E218
-#define CRYPTO_ENCR_PIP0_XTS_KEY7_REG		0x1E21C
 
-#define CRYPTO_ENCR_PIP1_XTS_KEY0_REG		0x1E220
-#define CRYPTO_ENCR_PIP1_XTS_KEY1_REG		0x1E224
-#define CRYPTO_ENCR_PIP1_XTS_KEY2_REG		0x1E228
-#define CRYPTO_ENCR_PIP1_XTS_KEY3_REG		0x1E22C
-#define CRYPTO_ENCR_PIP1_XTS_KEY4_REG		0x1E230
-#define CRYPTO_ENCR_PIP1_XTS_KEY5_REG		0x1E234
-#define CRYPTO_ENCR_PIP1_XTS_KEY6_REG		0x1E238
-#define CRYPTO_ENCR_PIP1_XTS_KEY7_REG		0x1E23C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY0_REG		0x1E200
+#define CRYPTO_ENCR_PIPE0_XTS_KEY1_REG		0x1E204
+#define CRYPTO_ENCR_PIPE0_XTS_KEY2_REG		0x1E208
+#define CRYPTO_ENCR_PIPE0_XTS_KEY3_REG		0x1E20C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY4_REG		0x1E210
+#define CRYPTO_ENCR_PIPE0_XTS_KEY5_REG		0x1E214
+#define CRYPTO_ENCR_PIPE0_XTS_KEY6_REG		0x1E218
+#define CRYPTO_ENCR_PIPE0_XTS_KEY7_REG		0x1E21C
 
-#define CRYPTO_ENCR_PIP2_XTS_KEY0_REG		0x1E240
-#define CRYPTO_ENCR_PIP2_XTS_KEY1_REG		0x1E244
-#define CRYPTO_ENCR_PIP2_XTS_KEY2_REG		0x1E248
-#define CRYPTO_ENCR_PIP2_XTS_KEY3_REG		0x1E24C
-#define CRYPTO_ENCR_PIP2_XTS_KEY4_REG		0x1E250
-#define CRYPTO_ENCR_PIP2_XTS_KEY5_REG		0x1E254
-#define CRYPTO_ENCR_PIP2_XTS_KEY6_REG		0x1E258
-#define CRYPTO_ENCR_PIP2_XTS_KEY7_REG		0x1E25C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY0_REG		0x1E220
+#define CRYPTO_ENCR_PIPE1_XTS_KEY1_REG		0x1E224
+#define CRYPTO_ENCR_PIPE1_XTS_KEY2_REG		0x1E228
+#define CRYPTO_ENCR_PIPE1_XTS_KEY3_REG		0x1E22C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY4_REG		0x1E230
+#define CRYPTO_ENCR_PIPE1_XTS_KEY5_REG		0x1E234
+#define CRYPTO_ENCR_PIPE1_XTS_KEY6_REG		0x1E238
+#define CRYPTO_ENCR_PIPE1_XTS_KEY7_REG		0x1E23C
 
-#define CRYPTO_ENCR_PIP3_XTS_KEY0_REG		0x1E260
-#define CRYPTO_ENCR_PIP3_XTS_KEY1_REG		0x1E264
-#define CRYPTO_ENCR_PIP3_XTS_KEY2_REG		0x1E268
-#define CRYPTO_ENCR_PIP3_XTS_KEY3_REG		0x1E26C
-#define CRYPTO_ENCR_PIP3_XTS_KEY4_REG		0x1E270
-#define CRYPTO_ENCR_PIP3_XTS_KEY5_REG		0x1E274
-#define CRYPTO_ENCR_PIP3_XTS_KEY6_REG		0x1E278
-#define CRYPTO_ENCR_PIP3_XTS_KEY7_REG		0x1E27C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY0_REG		0x1E240
+#define CRYPTO_ENCR_PIPE2_XTS_KEY1_REG		0x1E244
+#define CRYPTO_ENCR_PIPE2_XTS_KEY2_REG		0x1E248
+#define CRYPTO_ENCR_PIPE2_XTS_KEY3_REG		0x1E24C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY4_REG		0x1E250
+#define CRYPTO_ENCR_PIPE2_XTS_KEY5_REG		0x1E254
+#define CRYPTO_ENCR_PIPE2_XTS_KEY6_REG		0x1E258
+#define CRYPTO_ENCR_PIPE2_XTS_KEY7_REG		0x1E25C
+
+#define CRYPTO_ENCR_PIPE3_XTS_KEY0_REG		0x1E260
+#define CRYPTO_ENCR_PIPE3_XTS_KEY1_REG		0x1E264
+#define CRYPTO_ENCR_PIPE3_XTS_KEY2_REG		0x1E268
+#define CRYPTO_ENCR_PIPE3_XTS_KEY3_REG		0x1E26C
+#define CRYPTO_ENCR_PIPE3_XTS_KEY4_REG		0x1E270
+#define CRYPTO_ENCR_PIPE3_XTS_KEY5_REG		0x1E274
+#define CRYPTO_ENCR_PIPE3_XTS_KEY6_REG		0x1E278
+#define CRYPTO_ENCR_PIPE3_XTS_KEY7_REG		0x1E27C
 
 
 #define CRYPTO_CNTR0_IV0_REG			0x1A20C
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 10f8ae1..7016931 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -933,7 +933,8 @@
 	if (pdata->set_grp_async != NULL)
 		pdata->set_grp_async();
 
-	if (pdata->num_levels > KGSL_MAX_PWRLEVELS) {
+	if (pdata->num_levels > KGSL_MAX_PWRLEVELS ||
+	    pdata->num_levels < 1) {
 		KGSL_PWR_ERR(device, "invalid power level count: %d\n",
 					 pdata->num_levels);
 		result = -EINVAL;
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 490fac8..e57fcd8 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -25,6 +25,7 @@
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/kmemleak.h>
 
 #include <asm/sizes.h>
 
@@ -120,6 +121,8 @@
 		goto fail_mem;
 	}
 
+	kmemleak_not_leak(buf);
+
 	return 0;
 
 fail_mem:
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index 729450d..7716ccb 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, 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
diff --git a/drivers/power/bq28400_battery.c b/drivers/power/bq28400_battery.c
index 1852687..beab4e2 100644
--- a/drivers/power/bq28400_battery.c
+++ b/drivers/power/bq28400_battery.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013 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
@@ -136,6 +136,8 @@
 	struct power_supply	batt_psy;
 	struct power_supply	*dc_psy;
 	bool			is_charging_enabled;
+	u32			temp_cold;	/* in degree celsius */
+	u32			temp_hot;	/* in degree celsius */
 };
 
 static struct bq28400_device *bq28400_dev;
@@ -486,10 +488,14 @@
 	int rsoc;
 	s16 current_ma = 0;
 	u16 battery_status;
+	int temperature;
+	struct bq28400_device *dev = i2c_get_clientdata(client);
 
 	battery_status = bq28400_read_reg(client, SBS_BATTERY_STATUS);
 	rsoc = bq28400_read_rsoc(client);
 	current_ma = bq28400_read_current(client);
+	temperature = bq28400_read_temperature(client);
+	temperature = temperature / 10; /* in degree celsius */
 
 	if (battery_status & BAT_STATUS_EMPTY)
 		pr_debug("Battery report Empty.\n");
@@ -513,8 +519,11 @@
 		return POWER_SUPPLY_STATUS_FULL;
 	}
 
-	/* Enable charging when battery is not full */
-	bq28400_enable_charging(bq28400_dev, true);
+	/* Enable charging when battery is not full and temperature is ok */
+	if ((temperature > dev->temp_cold) && (temperature < dev->temp_hot))
+		bq28400_enable_charging(bq28400_dev, true);
+	else
+		bq28400_enable_charging(bq28400_dev, false);
 
 	/*
 	* Positive current indicates charging
@@ -825,6 +834,12 @@
 				   const struct i2c_device_id *id)
 {
 	int ret = 0;
+	struct device_node *dev_node = client->dev.of_node;
+
+	if (dev_node == NULL) {
+		pr_err("Device Tree node doesn't exist.\n");
+		return -ENODEV;
+	}
 
 	if (!i2c_check_functionality(client->adapter,
 				I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -843,6 +858,23 @@
 		return -ENOMEM;
 	}
 
+	/* Note: Lithium-ion battery normal temperature range 0..40 C */
+	ret = of_property_read_u32(dev_node, "ti,temp-cold",
+				   &(bq28400_dev->temp_cold));
+	if (ret) {
+		pr_err("Unable to read cold temperature. ret=%d.\n", ret);
+		goto err_dev_node;
+	}
+	pr_debug("cold temperature limit = %d C.\n", bq28400_dev->temp_cold);
+
+	ret = of_property_read_u32(dev_node, "ti,temp-hot",
+				   &(bq28400_dev->temp_hot));
+	if (ret) {
+		pr_err("Unable to read hot temperature. ret=%d.\n", ret);
+		goto err_dev_node;
+	}
+	pr_debug("hot temperature limit = %d C.\n", bq28400_dev->temp_hot);
+
 	bq28400_dev->client = client;
 	i2c_set_clientdata(client, bq28400_dev);
 
@@ -864,7 +896,7 @@
 	schedule_delayed_work(&bq28400_dev->periodic_user_space_update_work,
 			      msecs_to_jiffies(1000));
 
-	pr_info("Device is ready.\n");
+	pr_debug("Device is ready.\n");
 
 	return 0;
 
@@ -873,6 +905,7 @@
 		debugfs_remove_recursive(bq28400_dev->dent);
 	power_supply_unregister(&bq28400_dev->batt_psy);
 err_register_psy:
+err_dev_node:
 	kfree(bq28400_dev);
 	bq28400_dev = NULL;
 
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 8002e9e..63cab43 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -34,6 +34,8 @@
 /* Coulomb counter clear registers */
 #define BMS1_CC_DATA_CTL		0x42
 #define BMS1_CC_CLEAR_CTL		0x43
+/* BMS Tolerances */
+#define BMS1_TOL_CTL			0X44
 /* OCV limit registers */
 #define BMS1_OCV_USE_LOW_LIMIT_THR0	0x48
 #define BMS1_OCV_USE_LOW_LIMIT_THR1	0x49
@@ -203,6 +205,7 @@
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 };
 
+static bool bms_reset;
 
 static int qpnp_read_wrapper(struct qpnp_bms_chip *chip, u8 *val,
 			u16 base, int count)
@@ -889,6 +892,12 @@
 						chip->iavg_num_samples);
 	}
 
+	/*
+	 * if we're in bms reset mode, force uuc to be 3% of fcc
+	 */
+	if (bms_reset)
+		return (params->fcc_uah * 3) / 100;
+
 	uuc_uah_iavg = calculate_termination_uuc(chip, params, uuc_iavg_ma,
 						batt_temp, &pc_unusable);
 	pr_debug("uuc_iavg_ma = %d uuc with iavg = %d\n",
@@ -1177,6 +1186,76 @@
 	return soc;
 }
 
+#define IBAT_TOL_MASK		0x0F
+#define OCV_TOL_MASK		0xF0
+#define IBAT_TOL_DEFAULT	0x03
+#define IBAT_TOL_NOCHG		0x0F
+#define OCV_TOL_DEFAULT		0x20
+#define OCV_TOL_NO_OCV		0x00
+static int stop_ocv_updates(struct qpnp_bms_chip *chip)
+{
+	pr_debug("stopping ocv updates\n");
+	return qpnp_masked_write(chip, BMS1_TOL_CTL,
+			OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+
+static int reset_bms_for_test(struct qpnp_bms_chip *chip)
+{
+	int ibat_ua, vbat_uv, rc;
+	int ocv_est_uv;
+
+	if (!chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+
+	rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
+
+	ocv_est_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
+	pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
+	chip->last_ocv_uv = ocv_est_uv;
+	chip->last_soc = -EINVAL;
+	reset_cc(chip);
+	chip->last_cc_uah = INT_MIN;
+	stop_ocv_updates(chip);
+
+	pr_debug("bms reset to ocv = %duv vbat_ua = %d ibat_ua = %d\n",
+			chip->last_ocv_uv, vbat_uv, ibat_ua);
+
+	return rc;
+}
+
+static int bms_reset_set(const char *val, const struct kernel_param *kp)
+{
+	int rc;
+
+	rc = param_set_bool(val, kp);
+	if (rc) {
+		pr_err("Unable to set bms_reset: %d\n", rc);
+		return rc;
+	}
+
+	if (*(bool *)kp->arg) {
+		struct power_supply *bms_psy = power_supply_get_by_name("bms");
+		struct qpnp_bms_chip *chip = container_of(bms_psy,
+					struct qpnp_bms_chip, bms_psy);
+
+		rc = reset_bms_for_test(chip);
+		if (rc) {
+			pr_err("Unable to modify bms_reset: %d\n", rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+static struct kernel_param_ops bms_reset_ops = {
+	.set = bms_reset_set,
+	.get = param_get_bool,
+};
+
+module_param_cb(bms_reset, &bms_reset_ops, &bms_reset, 0644);
+
 static int charging_adjustments(struct qpnp_bms_chip *chip,
 				struct soc_params *params, int soc,
 				int vbat_uv, int ibat_ua, int batt_temp)
@@ -1268,6 +1347,12 @@
 				(s64)params->fcc_uah - params->uuc_uah);
 	soc_est = bound_soc(soc_est);
 
+	/* never adjust during bms reset mode */
+	if (bms_reset) {
+		pr_debug("bms reset mode, SOC adjustment skipped\n");
+		goto out;
+	}
+
 	if (ibat_ua < 0 && !is_batfet_open(chip)) {
 		soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua,
 				batt_temp);
@@ -1631,6 +1716,8 @@
 
 	chg_time_sec = DIV_ROUND_UP(chip->charge_time_us, USEC_PER_SEC);
 	catch_up_sec = DIV_ROUND_UP(chip->catch_up_time_us, USEC_PER_SEC);
+	if (catch_up_sec == 0)
+		return new_soc;
 	pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
 
 	/*
@@ -1730,8 +1817,7 @@
 	}
 
 	/* last_soc < soc  ... scale and catch up */
-	if (chip->last_soc != -EINVAL && chip->last_soc < soc
-			&& soc != 100 && chip->catch_up_time_us != 0)
+	if (chip->last_soc != -EINVAL && chip->last_soc < soc && soc != 100)
 		soc = scale_soc_while_chg(chip, delta_time_us,
 						soc, chip->last_soc);
 
diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c
index aae941e..f0d5c52 100644
--- a/drivers/usb/gadget/f_audio_source.c
+++ b/drivers/usb/gadget/f_audio_source.c
@@ -256,6 +256,8 @@
 	ktime_t				start_time;
 	/* number of frames sent since start_time */
 	s64				frames_sent;
+
+	bool				audio_ep_enabled;
 };
 
 static inline struct audio_dev *func_to_audio_source(struct usb_function *f)
@@ -525,18 +527,26 @@
 
 	pr_debug("audio_set_alt intf %d, alt %d\n", intf, alt);
 
-	ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep);
-	if (ret) {
-		audio->in_ep->desc = NULL;
-		ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
-				audio->in_ep->name, ret);
-			return ret;
-	}
-	ret = usb_ep_enable(audio->in_ep);
-	if (ret) {
-		ERROR(cdev, "failed to enable ep %s, result %d\n",
-			audio->in_ep->name, ret);
-		return ret;
+	if (intf == as_interface_alt_1_desc.bInterfaceNumber) {
+		if (alt && !audio->audio_ep_enabled) {
+			ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep);
+			if (ret) {
+				audio->in_ep->desc = NULL;
+				ERROR(cdev, "config_ep fail ep %s, result %d\n",
+						audio->in_ep->name, ret);
+				return ret;
+			}
+			ret = usb_ep_enable(audio->in_ep);
+			if (ret) {
+				ERROR(cdev, "failedto enable ep%s, result %d\n",
+					audio->in_ep->name, ret);
+				return ret;
+			}
+			audio->audio_ep_enabled = true;
+		} else if (!alt && audio->audio_ep_enabled) {
+			usb_ep_disable(audio->in_ep);
+			audio->audio_ep_enabled = false;
+		}
 	}
 	return 0;
 }
@@ -546,7 +556,10 @@
 	struct audio_dev *audio = func_to_audio_source(f);
 
 	pr_debug("audio_disable\n");
-	usb_ep_disable(audio->in_ep);
+	if (audio->audio_ep_enabled) {
+		usb_ep_disable(audio->in_ep);
+		audio->audio_ep_enabled = false;
+	}
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 9333e57..a3b92ed 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -829,6 +829,74 @@
 	return ret;
 }
 
+static ssize_t hdmi_common_rda_audio_data_block(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int adb_size	= 0;
+	int adb_count	= 0;
+	ssize_t ret	= 0;
+	char *data	= buf;
+
+	if (!external_common_state)
+		return 0;
+
+	adb_count = 1;
+	adb_size  = external_common_state->adb_size;
+	ret       = sizeof(adb_count) + sizeof(adb_size) + adb_size;
+
+	if (ret > PAGE_SIZE) {
+		DEV_DBG("%s: Insufficient buffer size\n", __func__);
+		return 0;
+	}
+
+	/* Currently only extracting one audio data block */
+	memcpy(data, &adb_count, sizeof(adb_count));
+	data += sizeof(adb_count);
+	memcpy(data, &adb_size, sizeof(adb_size));
+	data += sizeof(adb_size);
+	memcpy(data, external_common_state->audio_data_block,
+			external_common_state->adb_size);
+
+	print_hex_dump(KERN_DEBUG, "AUDIO DATA BLOCK: ", DUMP_PREFIX_NONE,
+			32, 8, buf, ret, false);
+
+	return ret;
+}
+
+static ssize_t hdmi_common_rda_spkr_alloc_data_block(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int sadb_size	= 0;
+	int sadb_count	= 0;
+	ssize_t ret	= 0;
+	char *data	= buf;
+
+	if (!external_common_state)
+		return 0;
+
+	sadb_count = 1;
+	sadb_size  = external_common_state->sadb_size;
+	ret        = sizeof(sadb_count) + sizeof(sadb_size) + sadb_size;
+
+	if (ret > PAGE_SIZE) {
+		DEV_DBG("%s: Insufficient buffer size\n", __func__);
+		return 0;
+	}
+
+	/* Currently only extracting one speaker allocation data block */
+	memcpy(data, &sadb_count, sizeof(sadb_count));
+	data += sizeof(sadb_count);
+	memcpy(data, &sadb_size, sizeof(sadb_size));
+	data += sizeof(sadb_size);
+	memcpy(data, external_common_state->spkr_alloc_data_block,
+			external_common_state->sadb_size);
+
+	print_hex_dump(KERN_DEBUG, "SPKR ALLOC DATA BLOCK: ", DUMP_PREFIX_NONE,
+			32, 8, buf, ret, false);
+
+	return ret;
+}
+
 static DEVICE_ATTR(video_mode, S_IRUGO | S_IWUGO,
 	external_common_rda_video_mode, external_common_wta_video_mode);
 static DEVICE_ATTR(video_mode_str, S_IRUGO, external_common_rda_video_mode_str,
@@ -859,6 +927,10 @@
 	hdmi_3d_wta_format_3d);
 #endif
 static DEVICE_ATTR(hdmi_primary, S_IRUGO, hdmi_common_rda_hdmi_primary, NULL);
+static DEVICE_ATTR(audio_data_block, S_IRUGO, hdmi_common_rda_audio_data_block,
+	NULL);
+static DEVICE_ATTR(spkr_alloc_data_block, S_IRUGO,
+	hdmi_common_rda_spkr_alloc_data_block, NULL);
 
 static struct attribute *external_common_fs_attrs[] = {
 	&dev_attr_video_mode.attr,
@@ -887,6 +959,8 @@
 	&dev_attr_cec_wr_frame.attr,
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
 	&dev_attr_hdmi_primary.attr,
+	&dev_attr_audio_data_block.attr,
+	&dev_attr_spkr_alloc_data_block.attr,
 	NULL,
 };
 static struct attribute_group external_common_fs_attr_group = {
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 80db0b2..a283e0a 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -588,10 +588,10 @@
 
 			msleep(20);
 			ret = mfd->off_fnc(mfd);
-			if (ret) {
+			if (ret)
 				mfd->panel_power_on = curr_pwr_state;
+			else
 				mdss_fb_release_fences(mfd);
-			}
 			mfd->op_enable = true;
 		}
 		break;
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 2f4c2ed..6030cbc 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -698,6 +698,14 @@
 		ctl->power_on = false;
 		ctl->play_cnt = 0;
 		ctl->clk_rate = 0;
+		if (ctl->mixer_left) {
+			mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
+					ctl->mixer_left->num), 0);
+		}
+		if (ctl->mixer_right) {
+			mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
+					ctl->mixer_right->num), 0);
+		}
 		mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
 	}
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index a1f1bcc..2c0ddda 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
@@ -265,6 +265,9 @@
 
 	ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data;
 	if (ctx) {
+		mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+				   NULL, NULL);
+
 		ctl->priv_data = NULL;
 		ctx->ref_cnt--;
 	}
@@ -318,8 +321,6 @@
 	flush_bits = BIT(16); /* WB */
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, flush_bits);
 
-	mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
-				   mdss_mdp_writeback_intr_done, ctx);
 	mdss_mdp_irq_enable(ctx->intr_type, ctx->intf_num);
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
@@ -353,6 +354,9 @@
 	ctx->wb_num = ctl->num;	/* wb num should match ctl num */
 	ctx->initialized = false;
 
+	mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+				   mdss_mdp_writeback_intr_done, ctx);
+
 	if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR)
 		ctl->prepare_fnc = mdss_mdp_writeback_prepare_rot;
 	else /* wfd or line mode */
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 75a926a..911e29f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -78,7 +78,7 @@
 			       void (*fnc_ptr)(void *), void *arg)
 {
 	unsigned long flags;
-	int index, ret;
+	int index;
 
 	index = mdss_mdp_intr2index(intr_type, intf_num);
 	if (index < 0) {
@@ -88,16 +88,13 @@
 	}
 
 	spin_lock_irqsave(&mdss_mdp_intr_lock, flags);
-	if (!mdp_intr_cb[index].func) {
-		mdp_intr_cb[index].func = fnc_ptr;
-		mdp_intr_cb[index].arg = arg;
-		ret = 0;
-	} else {
-		ret = -EBUSY;
-	}
+	WARN(mdp_intr_cb[index].func && fnc_ptr,
+		"replacing current intr callback for ndx=%d\n", index);
+	mdp_intr_cb[index].func = fnc_ptr;
+	mdp_intr_cb[index].arg = arg;
 	spin_unlock_irqrestore(&mdss_mdp_intr_lock, flags);
 
-	return ret;
+	return 0;
 }
 
 static inline void mdss_mdp_intr_done(int index)
diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h
index ec28463..3690160 100644
--- a/include/linux/test-iosched.h
+++ b/include/linux/test-iosched.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, 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
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index f29f02e..9558fa4 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, .qualcomm.com. All rights reserved.
+/* Copyright (c) 2010-2013, 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
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 6b957f6..a867991 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1353,6 +1353,9 @@
 	SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_MI2S_RX,
 	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer,
 	msm_routing_put_voice_stub_mixer),
+	SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_MI2S_RX,
+	MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new afe_pcm_rx_voice_mixer_controls[] = {
@@ -1455,6 +1458,9 @@
 	SOC_SINGLE_EXT("AUX_PCM_TX_VoLTE", MSM_BACKEND_DAI_AUXPCM_TX,
 	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
 	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("MI2S_TX_VoLTE", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
 };
 
 static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
@@ -2209,6 +2215,12 @@
 	{"HDMI", NULL, "HDMI_RX_Voice Mixer"},
 	{"HDMI", NULL, "HDMI_DL_HL"},
 
+	{"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+	{"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"MI2S_RX_Voice Mixer", "VoLTE", "VoLTE_DL"},
+	{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
+
 	{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
 	{"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"},
 	{"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"},
@@ -2221,6 +2233,7 @@
 	{"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"},
 	{"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"},
 	{"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"},
+	{"VoLTE_Tx Mixer", "MI2S_TX_VoLTE", "MI2S_TX"},
 	{"VoLTE_UL", NULL, "VoLTE_Tx Mixer"},
 	{"Voip_Tx Mixer", "PRI_TX_Voip", "PRI_I2S_TX"},
 	{"Voip_Tx Mixer", "MI2S_TX_Voip", "MI2S_TX"},
@@ -2276,12 +2289,6 @@
 	{"SLIMBUS_1_RX Mixer", "Voice Stub", "VOICE_STUB_DL"},
 	{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
 	{"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
-	{"MI2S_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
-	{"MI2S_RX_Voice Mixer", "Voip", "VOIP_DL"},
-	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
-	{"MI2S_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
-	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
-
 	{"SLIMBUS_3_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
 	{"SLIMBUS_3_RX", NULL, "SLIMBUS_3_RX_Voice Mixer"},