Merge "msm: kgsl: Synchronize access to IOMMU cfg port"
diff --git a/Documentation/devicetree/bindings/arm/msm/lpm-resources.txt b/Documentation/devicetree/bindings/arm/msm/lpm-resources.txt
index 7f2a21b..ccb3465 100644
--- a/Documentation/devicetree/bindings/arm/msm/lpm-resources.txt
+++ b/Documentation/devicetree/bindings/arm/msm/lpm-resources.txt
@@ -23,6 +23,7 @@
 - qcom,resource-type: The type of the LPM resource.
    MSM_LPM_RPM_RS_TYPE    = 0
    MSM_LPM_LOCAL_RS_TYPE  = 1
+- qcom,init-value: Initialization value of the LPM resource.
 
 
 Optional Nodes:
@@ -41,5 +42,6 @@
                         qcom,type = <0x62706d73>;   /* "smpb" */
                         qcom,id = <0x02>;
                         qcom,key = <0x6e726f63>;   /* "corn" */
+			qcom,init-value= <5>;   /* Active Corner*/
                 };
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 89c7417..53fd3b2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1889,7 +1889,6 @@
 
 config DONT_MAP_HOLE_AFTER_MEMBANK0
 	def_bool n
-	depends on SPARSEMEM
 
 config ARCH_ENABLE_MEMORY_HOTPLUG
 	def_bool n
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 6538db5..7a9a80d 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -83,7 +83,7 @@
 					  "ocv_for_r",
 					  "cc_thr";
 
-			qcom,bms-r-sense-mohm = <10>;
+			qcom,bms-r-sense-mohm = <2>;
 			qcom,bms-v-cutoff-uv = <3400000>;
 			qcom,bms-max-voltage-uv = <4200000>;
 			qcom,bms-r-conn-mohm = <18>;
@@ -95,7 +95,6 @@
 			qcom,bms-calculate-soc-ms = <20000>;
 			qcom,bms-chg-term-ua = <100000>;
 			qcom,bms-batt-type = <0>;
-			qcom,bms-use-voltage-soc;
 		};
 
 		clkdiv@5b00 {
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 927ebcd..a07788b 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -55,6 +55,13 @@
 		status = "disabled";
 	};
 
+	qcom,sps@f9984000 {
+		compatible = "qcom,msm_sps";
+		reg = <0xf9984000 0x15000>,
+		      <0xf9999000 0xb000>;
+		interrupts = <0 94 0>;
+	};
+
         usb@f9a55000 {
 		compatible = "qcom,hsusb-otg";
 		reg = <0xf9a55000 0x400>;
diff --git a/arch/arm/boot/dts/msm8974-pm.dtsi b/arch/arm/boot/dts/msm8974-pm.dtsi
index 52f2a41..c877134 100644
--- a/arch/arm/boot/dts/msm8974-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-pm.dtsi
@@ -143,6 +143,7 @@
 			qcom,type = <0x62706d73>;	/* "smpb" */
 			qcom,id = <0x02>;
 			qcom,key = <0x6e726f63>;	/* "corn" */
+			qcom,init-value = <5>;		/* Super Turbo */
 		};
 
 		qcom,lpm-resources@1 {
@@ -152,6 +153,7 @@
 			qcom,type = <0x62706d73>;	/* "smpb" */
 			qcom,id = <0x01>;
 			qcom,key = <0x7675>;		/* "uv" */
+			qcom,init-value = <1050000>;	/* Super Turbo */
 		};
 
 		qcom,lpm-resources@2 {
@@ -161,12 +163,14 @@
 			qcom,type = <0x306b6c63>;	/* "clk0" */
 			qcom,id = <0x00>;
 			qcom,key = <0x62616e45>;	/* "Enab" */
+			qcom,init-value = <1>;		/* On */
 		};
 
 		qcom,lpm-resources@3 {
 			reg = <0x3>;
 			qcom,name = "l2";
 			qcom,resource-type = <1>;
+			qcom,init-value = <2>;		/* Retention */
 		};
 	};
 
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 6a7e81e..406be59 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -188,8 +188,6 @@
 		qcom,vdd-voltage-level = <2950000 2950000>;
 		qcom,vdd-current-level = <9000 800000>;
 
-		qcom,vdd-io-always-on;
-		qcom,vdd-io-lpm-sup;
 		qcom,vdd-io-voltage-level = <1800000 2950000>;
 		qcom,vdd-io-current-level = <6 22000>;
 
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
index 2839864..dbdddb6 100644
--- a/arch/arm/boot/dts/msm9625-pm.dtsi
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -42,6 +42,7 @@
 			qcom,type = <0x616F646C>;       /* "ldoa" */
 			qcom,id = <0x0A>;
 			qcom,key = <0x6e726f63>;	/* "corn" */
+			qcom,init-value = <5>;		/* Super Turbo */
 		};
 
 		qcom,lpm-resources@1 {
@@ -51,6 +52,7 @@
 			qcom,type = <0x616F646C>;       /* "ldoa" */
 			qcom,id = <0x0C>;
 			qcom,key =  <0x7675>;		/* "uv" */
+			qcom,init-value = <1050000>;	/* Super Turbo */
 		};
 
 		qcom,lpm-resources@2 {
@@ -60,6 +62,7 @@
 			qcom,type = <0x306b6c63>;	/* "clk0" */
 			qcom,id = <0x00>;
 			qcom,key = <0x62616e45>;	/* "Enab" */
+			qcom,init-value = <1>;		/* On */
 		};
 	};
 
diff --git a/arch/arm/configs/msm8910_defconfig b/arch/arm/configs/msm8910_defconfig
index de78559..b49a83f 100644
--- a/arch/arm/configs/msm8910_defconfig
+++ b/arch/arm/configs/msm8910_defconfig
@@ -47,6 +47,7 @@
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
+CONFIG_SCHED_MC=y
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_HOTPLUG_CPU=y
 CONFIG_PREEMPT=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 1fe1eaa..e5fd0d5 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -100,6 +100,7 @@
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
+CONFIG_SCHED_MC=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 01d1934..02756e9 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -105,6 +105,7 @@
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
+CONFIG_SCHED_MC=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 71e83f6..94e2f36 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -77,6 +77,7 @@
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
+CONFIG_SCHED_MC=y
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
@@ -283,6 +284,7 @@
 CONFIG_SENSORS_QPNP_ADC_CURRENT=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_MONITOR=y
 CONFIG_THERMAL_QPNP=y
 CONFIG_WCD9320_CODEC=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index ffcc83f..0e9bf1d 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -79,6 +79,7 @@
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
+CONFIG_SCHED_MC=y
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
@@ -285,6 +286,7 @@
 CONFIG_SENSORS_QPNP_ADC_CURRENT=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8974=y
+CONFIG_THERMAL_MONTIOR=y
 CONFIG_THERMAL_QPNP=y
 CONFIG_WCD9320_CODEC=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 5e51bb8..e6255f2 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -505,7 +505,7 @@
 
 config MSM_MPM_OF
 	bool "Modem Power Manager"
-	depends on CONFIG_OF
+	depends on OF
 	help
 	  MPM is a dedicated hardware resource responsible for entering and
 	  waking up from a system wide low power mode. The MPM driver tracks
@@ -2112,7 +2112,7 @@
 
 config MSM_BUSPM_DEV
 	tristate "MSM Bus Performance Monitor Kernel Module"
-	depends on (ARCH_MSM8X60 || ARCH_MSM8960)
+	depends on (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM8974)
 	default m
 	help
 	  This kernel module is used to mmap() hardware registers for the
@@ -2265,7 +2265,7 @@
 
 config MSM_RUN_QUEUE_STATS
 	bool "Enable collection and exporting of MSM Run Queue stats to userspace"
-	depends on (MSM_SOC_REV_A || ARCH_MSM8X60 || ARCH_MSM8960)
+	default n
 	help
 	 This option enalbes statistics collection on Run Queue. A daemon
          in user mode, called MPDecision will be using this data to decide
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 26aa32c..af77726 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -28,7 +28,7 @@
 ifdef CONFIG_ARCH_MSM_KRAIT
 obj-$(CONFIG_DEBUG_FS) += acpuclock-krait-debug.o
 endif
-obj-$(CONFIG_ARCH_MSM7X27) += acpuclock-7627.o clock-pll.o
+obj-$(CONFIG_ARCH_MSM7X27) += acpuclock-7627.o acpuclock-8625q.o clock-pll.o
 obj-$(CONFIG_ARCH_MSM_SCORPION) += pmu.o
 obj-$(CONFIG_ARCH_MSM_SCORPIONMP) += perf_event_msm_l2.o
 obj-$(CONFIG_ARCH_MSM_KRAIT) += msm-krait-l2-accessors.o pmu.o perf_event_msm_krait_l2.o
diff --git a/arch/arm/mach-msm/acpuclock-8625q.c b/arch/arm/mach-msm/acpuclock-8625q.c
new file mode 100644
index 0000000..00022ff
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8625q.c
@@ -0,0 +1,762 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2012, 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/sort.h>
+#include <linux/regulator/consumer.h>
+#include <linux/smp.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/clk-provider.h>
+
+#include <asm/cpu.h>
+
+#include "acpuclock.h"
+#include "acpuclock-8625q.h"
+
+#define A11S_CLK_CNTL_ADDR	(MSM_CSR_BASE + 0x100)
+#define A11S_CLK_SEL_ADDR	(MSM_CSR_BASE + 0x104)
+
+#define PLL4_L_VAL_ADDR		(MSM_CLK_CTL_BASE + 0x378)
+#define PLL4_M_VAL_ADDR		(MSM_CLK_CTL_BASE + 0x37C)
+#define PLL4_N_VAL_ADDR		(MSM_CLK_CTL_BASE + 0x380)
+
+#define POWER_COLLAPSE_KHZ 19200
+
+/* Max CPU frequency allowed by hardware while in standby waiting for an irq. */
+#define MAX_WAIT_FOR_IRQ_KHZ 128000
+
+/**
+ * enum - For acpuclock PLL IDs
+ */
+enum {
+	ACPU_PLL_0	= 0,
+	ACPU_PLL_1,
+	ACPU_PLL_2,
+	ACPU_PLL_3,
+	ACPU_PLL_4,
+	ACPU_PLL_TCXO,
+	ACPU_PLL_END,
+};
+
+struct acpu_clk_src {
+	struct clk *clk;
+	const char *name;
+};
+
+struct pll_config {
+	unsigned int l;
+	unsigned int m;
+	unsigned int n;
+};
+
+static struct acpu_clk_src pll_clk[ACPU_PLL_END] = {
+	[ACPU_PLL_0] = { .name = "pll0_clk" },
+	[ACPU_PLL_1] = { .name = "pll1_clk" },
+	[ACPU_PLL_2] = { .name = "pll2_clk" },
+	[ACPU_PLL_4] = { .name = "pll4_clk" },
+};
+
+static struct pll_config pll4_cfg_tbl[] = {
+	[0] = {  36, 1, 2 }, /*  700.8 MHz */
+	[1] = {  52, 1, 2 }, /* 1008 MHz */
+	[2] = {  63, 0, 1 }, /* 1209.6 MHz */
+	[3] = {  73, 0, 1 }, /* 1401.6 MHz */
+};
+
+struct clock_state {
+	struct clkctl_acpu_speed	*current_speed;
+	struct mutex			lock;
+	uint32_t			max_speed_delta_khz;
+	struct clk			*ebi1_clk;
+	struct regulator		*vreg_cpu;
+};
+
+struct clkctl_acpu_speed {
+	unsigned int	use_for_scaling;
+	unsigned int	a11clk_khz;
+	int		pll;
+	unsigned int	a11clk_src_sel;
+	unsigned int	a11clk_src_div;
+	unsigned int	ahbclk_khz;
+	unsigned int	ahbclk_div;
+	int		vdd;
+	unsigned int	axiclk_khz;
+	struct pll_config *pll_rate;
+	unsigned long   lpj;
+};
+
+static struct clock_state drv_state = { 0 };
+
+/* PVS MAX Voltage in uV as per frequencies*/
+
+# define MAX_14GHZ_VOLTAGE 1350000
+# define MAX_12GHZ_VOLTAGE 1275000
+# define MAX_1GHZ_VOLTAGE 1175000
+# define MAX_NOMINAL_VOLTAGE 1150000
+
+/* PVS deltas as per formula*/
+# define DELTA_LEVEL_1_UV 0
+# define DELTA_LEVEL_2_UV 75000
+# define DELTA_LEVEL_3_UV 150000
+
+
+static struct clkctl_acpu_speed acpu_freq_tbl_cmn[] = {
+	{ 0, 19200, ACPU_PLL_TCXO, 0, 0, 2400, 3, 0, 30720 },
+	{ 1, 245760, ACPU_PLL_1, 1, 0, 30720, 3, MAX_NOMINAL_VOLTAGE, 61440 },
+	{ 1, 320000, ACPU_PLL_0, 4, 2, 40000, 3, MAX_NOMINAL_VOLTAGE, 122880 },
+	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, MAX_NOMINAL_VOLTAGE, 122880 },
+	{ 0, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 0, 160000 },
+	{ 1, 700800, ACPU_PLL_4, 6, 0, 87500, 3, MAX_NOMINAL_VOLTAGE, 160000,
+						&pll4_cfg_tbl[0]},
+	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, MAX_1GHZ_VOLTAGE, 200000,
+						&pll4_cfg_tbl[1]},
+};
+
+static struct clkctl_acpu_speed acpu_freq_tbl_1209[] = {
+	{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, MAX_12GHZ_VOLTAGE, 200000,
+						&pll4_cfg_tbl[2]},
+};
+
+static struct clkctl_acpu_speed acpu_freq_tbl_1401[] = {
+	{ 1, 1401600, ACPU_PLL_4, 6, 0, 175000, 3, MAX_14GHZ_VOLTAGE, 200000,
+						&pll4_cfg_tbl[3]},
+};
+
+/* Entry corresponding to CDMA build*/
+static struct clkctl_acpu_speed acpu_freq_tbl_196608[] = {
+	{ 1, 196608, ACPU_PLL_1, 1, 0,  65536, 2, MAX_NOMINAL_VOLTAGE, 98304 },
+};
+
+static struct clkctl_acpu_speed acpu_freq_tbl_null[] = {
+	{ 0 },
+};
+
+static struct clkctl_acpu_speed acpu_freq_tbl[ARRAY_SIZE(acpu_freq_tbl_cmn)
+	+ ARRAY_SIZE(acpu_freq_tbl_1209)
+	+ ARRAY_SIZE(acpu_freq_tbl_1401)
+	+ ARRAY_SIZE(acpu_freq_tbl_null)];
+
+/* Switch to this when reprogramming PLL4 */
+static struct clkctl_acpu_speed *backup_s;
+
+#ifdef CONFIG_CPU_FREQ_MSM
+static struct cpufreq_frequency_table freq_table[NR_CPUS][20];
+
+static void __devinit cpufreq_table_init(void)
+{
+	int cpu;
+	for_each_possible_cpu(cpu) {
+		unsigned int i, freq_cnt = 0;
+
+		/* Construct the freq_table table from acpu_freq_tbl since
+		 * the freq_table values need to match frequencies specified
+		 * in acpu_freq_tbl and acpu_freq_tbl needs to be fixed up
+		 * during init.
+		 */
+		for (i = 0; acpu_freq_tbl[i].a11clk_khz != 0
+				&& freq_cnt < ARRAY_SIZE(*freq_table)-1; i++) {
+			if (acpu_freq_tbl[i].use_for_scaling) {
+				freq_table[cpu][freq_cnt].index = freq_cnt;
+				freq_table[cpu][freq_cnt].frequency
+					= acpu_freq_tbl[i].a11clk_khz;
+				freq_cnt++;
+			}
+		}
+
+		/* freq_table not big enough to store all usable freqs. */
+		BUG_ON(acpu_freq_tbl[i].a11clk_khz != 0);
+
+		freq_table[cpu][freq_cnt].index = freq_cnt;
+		freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
+		/* Register table with CPUFreq. */
+		cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
+		pr_info("CPU%d: %d scaling frequencies supported.\n",
+			cpu, freq_cnt);
+	}
+}
+#else
+static void __devinit cpufreq_table_init(void) { }
+#endif
+
+static void update_jiffies(int cpu, unsigned long loops)
+{
+#ifdef CONFIG_SMP
+	for_each_possible_cpu(cpu) {
+		per_cpu(cpu_data, cpu).loops_per_jiffy =
+						loops;
+	}
+#endif
+	/* Adjust the global one */
+	loops_per_jiffy = loops;
+}
+
+/* Assumes PLL4 is off and the acpuclock isn't sourced from PLL4 */
+static void acpuclk_config_pll4(struct pll_config *pll)
+{
+	/*
+	 * Make sure write to disable PLL_4 has completed
+	 * before reconfiguring that PLL.
+	*/
+	mb();
+	writel_relaxed(pll->l, PLL4_L_VAL_ADDR);
+	writel_relaxed(pll->m, PLL4_M_VAL_ADDR);
+	writel_relaxed(pll->n, PLL4_N_VAL_ADDR);
+	/* Make sure PLL is programmed before returning. */
+	mb();
+}
+
+/* Set proper dividers for the given clock speed. */
+static void acpuclk_set_div(const struct clkctl_acpu_speed *hunt_s)
+{
+	uint32_t reg_clkctl, reg_clksel, clk_div, src_sel;
+
+	reg_clksel = readl_relaxed(A11S_CLK_SEL_ADDR);
+
+	/* AHB_CLK_DIV */
+	clk_div = (reg_clksel >> 1) & 0x03;
+	/* CLK_SEL_SRC1NO */
+	src_sel = reg_clksel & 1;
+
+	/*
+	 * If the new clock divider is higher than the previous, then
+	 * program the divider before switching the clock
+	 */
+	if (hunt_s->ahbclk_div > clk_div) {
+		reg_clksel &= ~(0x3 << 1);
+		reg_clksel |= (hunt_s->ahbclk_div << 1);
+		writel_relaxed(reg_clksel, A11S_CLK_SEL_ADDR);
+	}
+
+	/* Program clock source and divider */
+	reg_clkctl = readl_relaxed(A11S_CLK_CNTL_ADDR);
+	reg_clkctl &= ~(0xFF << (8 * src_sel));
+	reg_clkctl |= hunt_s->a11clk_src_sel << (4 + 8 * src_sel);
+	reg_clkctl |= hunt_s->a11clk_src_div << (0 + 8 * src_sel);
+	writel_relaxed(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+	/* Program clock source selection */
+	reg_clksel ^= 1;
+	writel_relaxed(reg_clksel, A11S_CLK_SEL_ADDR);
+
+	/* Wait for the clock switch to complete */
+	mb();
+	udelay(50);
+
+	/*
+	 * If the new clock divider is lower than the previous, then
+	 * program the divider after switching the clock
+	 */
+	if (hunt_s->ahbclk_div < clk_div) {
+		reg_clksel &= ~(0x3 << 1);
+		reg_clksel |= (hunt_s->ahbclk_div << 1);
+		writel_relaxed(reg_clksel, A11S_CLK_SEL_ADDR);
+	}
+}
+
+static int acpuclk_set_vdd_level(int vdd)
+{
+	int rc;
+
+	rc = regulator_set_voltage(drv_state.vreg_cpu, vdd, vdd);
+	if (rc) {
+		pr_err("failed to set vdd=%d uV\n", vdd);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int acpuclk_8625q_set_rate(int cpu, unsigned long rate,
+					enum setrate_reason reason)
+{
+	uint32_t reg_clkctl;
+	struct clkctl_acpu_speed *cur_s, *tgt_s, *strt_s;
+	int res, rc = 0;
+	unsigned int plls_enabled = 0, pll;
+	int delta;
+
+
+	if (reason == SETRATE_CPUFREQ)
+		mutex_lock(&drv_state.lock);
+
+	strt_s = cur_s = drv_state.current_speed;
+
+	WARN_ONCE(cur_s == NULL, "%s: not initialized\n", __func__);
+	if (cur_s == NULL) {
+		rc = -ENOENT;
+		goto out;
+	}
+
+	cur_s->vdd = regulator_get_voltage(drv_state.vreg_cpu);
+	if (cur_s->vdd <= 0)
+		goto out;
+
+	pr_debug("current freq=%dKhz vdd=%duV\n",
+			cur_s->a11clk_khz, cur_s->vdd);
+
+	if (rate == cur_s->a11clk_khz)
+		goto out;
+
+	for (tgt_s = acpu_freq_tbl; tgt_s->a11clk_khz != 0; tgt_s++) {
+		if (tgt_s->a11clk_khz == rate)
+			break;
+	}
+
+	if (tgt_s->a11clk_khz == 0) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Choose the highest speed at or below 'rate' with same PLL. */
+	if (reason != SETRATE_CPUFREQ
+		&& tgt_s->a11clk_khz < cur_s->a11clk_khz) {
+		while (tgt_s->pll != ACPU_PLL_TCXO &&
+					tgt_s->pll != cur_s->pll) {
+			pr_debug("Intermediate frequency changes: %u\n",
+					tgt_s->a11clk_khz);
+			tgt_s--;
+		}
+	}
+
+	if (strt_s->pll != ACPU_PLL_TCXO)
+		plls_enabled |= 1 << strt_s->pll;
+
+	/* Need to do this when coming out of power collapse since some modem
+	 * firmwares reset the VDD when the application processor enters power
+	 * collapse.
+	 */
+	if (reason == SETRATE_CPUFREQ || reason == SETRATE_PC) {
+		/* Increase VDD if needed. */
+		if (tgt_s->vdd > cur_s->vdd) {
+			rc = acpuclk_set_vdd_level(tgt_s->vdd);
+			if (rc < 0) {
+				pr_err("Unable to switch ACPU vdd (%d)\n", rc);
+				goto out;
+			}
+			pr_debug("Increased Vdd to %duV\n", tgt_s->vdd);
+		}
+	}
+
+	/* Set wait states for CPU inbetween frequency changes */
+	reg_clkctl = readl_relaxed(A11S_CLK_CNTL_ADDR);
+	reg_clkctl |= (100 << 16); /* set WT_ST_CNT */
+	writel_relaxed(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+	pr_debug("Switching from ACPU rate %u KHz -> %u KHz\n",
+			strt_s->a11clk_khz, tgt_s->a11clk_khz);
+
+	delta = abs((int)(strt_s->a11clk_khz - tgt_s->a11clk_khz));
+
+	if (tgt_s->pll == ACPU_PLL_4) {
+		if (strt_s->pll == ACPU_PLL_4 ||
+				delta > drv_state.max_speed_delta_khz) {
+			/*
+			 * Enable the backup PLL if required
+			 * and switch to it.
+			 */
+			clk_enable(pll_clk[backup_s->pll].clk);
+			acpuclk_set_div(backup_s);
+			update_jiffies(cpu, backup_s->lpj);
+		}
+		/* Make sure PLL4 is off before reprogramming */
+		if ((plls_enabled & (1 << tgt_s->pll))) {
+			clk_disable(pll_clk[tgt_s->pll].clk);
+			plls_enabled &= ~(1 << tgt_s->pll);
+		}
+		acpuclk_config_pll4(tgt_s->pll_rate);
+		pll_clk[tgt_s->pll].clk->rate = tgt_s->a11clk_khz*1000;
+
+	} else if (strt_s->pll == ACPU_PLL_4) {
+		if (delta > drv_state.max_speed_delta_khz) {
+			/*
+			 * Enable the bcackup PLL if required
+			 * and switch to it.
+			 */
+			clk_enable(pll_clk[backup_s->pll].clk);
+			acpuclk_set_div(backup_s);
+			update_jiffies(cpu, backup_s->lpj);
+		}
+	}
+
+	if ((tgt_s->pll != ACPU_PLL_TCXO) &&
+			!(plls_enabled & (1 << tgt_s->pll))) {
+		rc = clk_enable(pll_clk[tgt_s->pll].clk);
+		if (rc < 0) {
+			pr_err("PLL%d enable failed (%d)\n",
+					tgt_s->pll, rc);
+			goto out;
+		}
+		plls_enabled |= 1 << tgt_s->pll;
+	}
+	acpuclk_set_div(tgt_s);
+	drv_state.current_speed = tgt_s;
+	pr_debug("The new clock speed is %u\n", tgt_s->a11clk_khz);
+	/* Re-adjust lpj for the new clock speed. */
+	update_jiffies(cpu, tgt_s->lpj);
+
+	/* Disable the backup PLL */
+	if ((delta > drv_state.max_speed_delta_khz)
+			|| (strt_s->pll == ACPU_PLL_4 &&
+				tgt_s->pll == ACPU_PLL_4))
+		clk_disable(pll_clk[backup_s->pll].clk);
+
+	/* Nothing else to do for SWFI. */
+	if (reason == SETRATE_SWFI)
+		goto out;
+
+	/* Change the AXI bus frequency if we can. */
+	if (reason != SETRATE_PC &&
+		strt_s->axiclk_khz != tgt_s->axiclk_khz) {
+		res = clk_set_rate(drv_state.ebi1_clk,
+				tgt_s->axiclk_khz * 1000);
+		pr_debug("AXI bus set freq %d\n",
+				tgt_s->axiclk_khz * 1000);
+		if (res < 0)
+			pr_warning("Setting AXI min rate failed (%d)\n", res);
+	}
+
+	/* Disable PLLs we are not using anymore. */
+	if (tgt_s->pll != ACPU_PLL_TCXO)
+		plls_enabled &= ~(1 << tgt_s->pll);
+	for (pll = ACPU_PLL_0; pll < ACPU_PLL_END; pll++)
+		if (plls_enabled & (1 << pll))
+			clk_disable(pll_clk[pll].clk);
+
+	/* Nothing else to do for power collapse. */
+	if (reason == SETRATE_PC)
+		goto out;
+
+	/* Drop VDD level if we can. */
+	if (tgt_s->vdd < strt_s->vdd) {
+		res = acpuclk_set_vdd_level(tgt_s->vdd);
+		if (res < 0)
+			pr_warning("Unable to drop ACPU vdd (%d)\n", res);
+		pr_debug("Decreased Vdd to %duV\n", tgt_s->vdd);
+	}
+
+	pr_debug("ACPU speed change complete\n");
+out:
+	if (reason == SETRATE_CPUFREQ)
+		mutex_unlock(&drv_state.lock);
+
+	return rc;
+}
+
+static int __devinit acpuclk_hw_init(void)
+{
+	struct clkctl_acpu_speed *speed;
+	uint32_t div, sel, reg_clksel;
+	int res;
+
+	/*
+	 * Prepare all the PLLs because we enable/disable them
+	 * from atomic context and can't always ensure they're
+	 * all prepared in non-atomic context. Same goes for
+	 * ebi1_acpu_clk.
+	 */
+	BUG_ON(clk_prepare(pll_clk[ACPU_PLL_0].clk));
+	BUG_ON(clk_prepare(pll_clk[ACPU_PLL_1].clk));
+	BUG_ON(clk_prepare(pll_clk[ACPU_PLL_2].clk));
+	BUG_ON(clk_prepare(pll_clk[ACPU_PLL_4].clk));
+	BUG_ON(clk_prepare(drv_state.ebi1_clk));
+
+	/*
+	 * Determine the rate of ACPU clock
+	 */
+
+	if (!(readl_relaxed(A11S_CLK_SEL_ADDR) & 0x01)) { /* CLK_SEL_SRC1N0 */
+		/* CLK_SRC0_SEL */
+		sel = (readl_relaxed(A11S_CLK_CNTL_ADDR) >> 12) & 0x7;
+		/* CLK_SRC0_DIV */
+		div = (readl_relaxed(A11S_CLK_CNTL_ADDR) >> 8) & 0x0f;
+	} else {
+		/* CLK_SRC1_SEL */
+		sel = (readl_relaxed(A11S_CLK_CNTL_ADDR) >> 4) & 0x07;
+		/* CLK_SRC1_DIV */
+		div = readl_relaxed(A11S_CLK_CNTL_ADDR) & 0x0f;
+	}
+
+	for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) {
+		if (speed->a11clk_src_sel == sel
+			&& (speed->a11clk_src_div == div))
+			break;
+	}
+	if (speed->a11clk_khz == 0) {
+		pr_err("Error - ACPU clock reports invalid speed\n");
+		return -EINVAL;
+	}
+
+	drv_state.current_speed = speed;
+	if (speed->pll != ACPU_PLL_TCXO) {
+		if (clk_enable(pll_clk[speed->pll].clk)) {
+			pr_warning("Failed to vote for boot PLL\n");
+			return -ENODEV;
+		}
+	}
+
+	reg_clksel = readl_relaxed(A11S_CLK_SEL_ADDR);
+	reg_clksel &= ~(0x3 << 14);
+	reg_clksel |= (0x1 << 14);
+	writel_relaxed(reg_clksel, A11S_CLK_SEL_ADDR);
+
+	res = clk_set_rate(drv_state.ebi1_clk, speed->axiclk_khz * 1000);
+	if (res < 0) {
+		pr_warning("Setting AXI min rate failed (%d)\n", res);
+		return -ENODEV;
+	}
+	res = clk_enable(drv_state.ebi1_clk);
+	if (res < 0) {
+		pr_warning("Enabling AXI clock failed (%d)\n", res);
+		return -ENODEV;
+	}
+
+	drv_state.vreg_cpu = regulator_get(NULL, "vddx_cx");
+	if (IS_ERR(drv_state.vreg_cpu)) {
+		res = PTR_ERR(drv_state.vreg_cpu);
+		pr_err("could not get regulator: %d\n", res);
+	}
+
+	pr_info("ACPU running at %d KHz\n", speed->a11clk_khz);
+	return 0;
+}
+
+static unsigned long acpuclk_8625q_get_rate(int cpu)
+{
+	WARN_ONCE(drv_state.current_speed == NULL,
+			"%s: not initialized\n", __func__);
+	if (drv_state.current_speed)
+		return drv_state.current_speed->a11clk_khz;
+	else
+		return 0;
+}
+
+#define MHZ 1000000
+
+static void __devinit select_freq_plan(unsigned int pvs_voltage)
+{
+	unsigned long pll_mhz[ACPU_PLL_END];
+	int i;
+	int size;
+	int delta[3] = {DELTA_LEVEL_1_UV, DELTA_LEVEL_2_UV, DELTA_LEVEL_3_UV};
+	struct clkctl_acpu_speed *tbl;
+
+	/* Get PLL clocks */
+	for (i = 0; i < ACPU_PLL_END; i++) {
+		if (pll_clk[i].name) {
+			pll_clk[i].clk = clk_get_sys("acpu", pll_clk[i].name);
+			if (IS_ERR(pll_clk[i].clk)) {
+				pll_mhz[i] = 0;
+				continue;
+			}
+			/* Get PLL's Rate */
+			pll_mhz[i] = clk_get_rate(pll_clk[i].clk)/MHZ;
+		}
+	}
+
+	memcpy(acpu_freq_tbl, acpu_freq_tbl_cmn, sizeof(acpu_freq_tbl_cmn));
+	size = ARRAY_SIZE(acpu_freq_tbl_cmn);
+
+	i = 0;		/* needed if we have a 1Ghz part */
+	/* select if it is a 1.2Ghz part */
+	if (pll_mhz[ACPU_PLL_4] == 1209) {
+		memcpy(acpu_freq_tbl + size, acpu_freq_tbl_1209,
+						sizeof(acpu_freq_tbl_1209));
+		size += sizeof(acpu_freq_tbl_1209);
+		i = 1;		/* set the delta index */
+	}
+	/* select if it is a 1.4Ghz part */
+	if (pll_mhz[ACPU_PLL_4] == 1401) {
+		memcpy(acpu_freq_tbl + size, acpu_freq_tbl_1209,
+						sizeof(acpu_freq_tbl_1209));
+		size += ARRAY_SIZE(acpu_freq_tbl_1209);
+		memcpy(acpu_freq_tbl + size, acpu_freq_tbl_1401,
+						sizeof(acpu_freq_tbl_1401));
+		size += ARRAY_SIZE(acpu_freq_tbl_1401);
+		i = 2;		/* set the delta index */
+	}
+
+	memcpy(acpu_freq_tbl + size, acpu_freq_tbl_null,
+						sizeof(acpu_freq_tbl_null));
+	size += sizeof(acpu_freq_tbl_null);
+
+	/* Alter the freq value in freq_tbl if it is a CDMA build*/
+	if (pll_mhz[ACPU_PLL_1] == 196) {
+
+		for (tbl = acpu_freq_tbl; tbl->a11clk_khz; tbl++) {
+			if (tbl->a11clk_khz == 245760 &&
+					tbl->pll == ACPU_PLL_1) {
+				pr_debug("Upgrading pll1 freq to 196  Mhz\n");
+				memcpy(tbl, acpu_freq_tbl_196608,
+						sizeof(acpu_freq_tbl_196608));
+				break;
+			}
+		}
+	}
+
+	/*
+	 *PVS Voltage calculation  formula
+	 *1.4 Ghz device
+	 *1.4 Ghz: Max(PVS_voltage,1.35V)
+	 *1.2 Ghz: Max(PVS_volatge - 75mV,1.275V)
+	 *1.0 Ghz: Max(PVS_voltage - 150mV, 1.175V)
+	 *1.2 Ghz device
+	 *1.2 Ghz: Max(PVS_voltage,1.275V)
+	 *1.0 Ghz: Max(PVS_volatge - 75mV,1.175V)
+	 *Nominal Mode: 1.15V
+	*/
+	for (tbl = acpu_freq_tbl; tbl->a11clk_khz; tbl++) {
+		if (tbl->a11clk_khz >= 1008000) {
+			/*
+			 * Change voltage as per PVS formula,
+			 * i is initialized above with 2 or 1
+			 * depending upon whether it is a 1.4Ghz
+			 * or 1.2Ghz, so, we get the proper value
+			 * from delta[i] which is to be deducted
+			 * from PVS voltage.
+			*/
+
+			tbl->vdd = max((int)(pvs_voltage - delta[i]), tbl->vdd);
+			i--;
+		}
+	}
+
+
+	/* find the backup PLL entry from the table */
+	for (tbl = acpu_freq_tbl; tbl->a11clk_khz; tbl++) {
+		if (tbl->pll == ACPU_PLL_2 &&
+				tbl->a11clk_src_div == 1) {
+			backup_s = tbl;
+			break;
+		}
+	}
+
+	BUG_ON(!backup_s);
+
+}
+
+/*
+ * Hardware requires the CPU to be dropped to less than MAX_WAIT_FOR_IRQ_KHZ
+ * before entering a wait for irq low-power mode. Find a suitable rate.
+ */
+static unsigned long __devinit find_wait_for_irq_khz(void)
+{
+	unsigned long found_khz = 0;
+	int i;
+
+	for (i = 0; acpu_freq_tbl[i].a11clk_khz &&
+		acpu_freq_tbl[i].a11clk_khz <= MAX_WAIT_FOR_IRQ_KHZ; i++)
+		found_khz = acpu_freq_tbl[i].a11clk_khz;
+
+	return found_khz;
+}
+
+static void __devinit lpj_init(void)
+{
+	int i = 0, cpu;
+	const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
+	unsigned long loops;
+
+	for_each_possible_cpu(cpu) {
+#ifdef CONFIG_SMP
+		loops = per_cpu(cpu_data, cpu).loops_per_jiffy;
+#else
+		loops = loops_per_jiffy;
+#endif
+		for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
+			acpu_freq_tbl[i].lpj = cpufreq_scale(
+				loops,
+				base_clk->a11clk_khz,
+				acpu_freq_tbl[i].a11clk_khz);
+		}
+
+	}
+
+}
+
+static struct acpuclk_data acpuclk_8625q_data = {
+	.set_rate = acpuclk_8625q_set_rate,
+	.get_rate = acpuclk_8625q_get_rate,
+	.power_collapse_khz = POWER_COLLAPSE_KHZ,
+	.switch_time_us = 50,
+};
+
+static void __devinit print_acpu_freq_tbl(void)
+{
+	struct clkctl_acpu_speed *t;
+	int i;
+
+	pr_info("Id CPU-KHz PLL DIV AHB-KHz ADIV AXI-KHz Vdd\n");
+
+	t = &acpu_freq_tbl[0];
+	for (i = 0; t->a11clk_khz != 0; i++) {
+		pr_info("%2d %7d %3d %3d %7d %4d %7d %3d\n",
+			i, t->a11clk_khz, t->pll, t->a11clk_src_div + 1,
+			t->ahbclk_khz, t->ahbclk_div + 1, t->axiclk_khz,
+			t->vdd);
+		t++;
+	}
+}
+
+static int __devinit acpuclk_8625q_probe(struct platform_device *pdev)
+{
+	const struct acpuclk_pdata_8625q *pdata = pdev->dev.platform_data;
+	unsigned int pvs_voltage = pdata->pvs_voltage_uv;
+
+	drv_state.max_speed_delta_khz = pdata->acpu_clk_data->
+						max_speed_delta_khz;
+
+	drv_state.ebi1_clk = clk_get(NULL, "ebi1_acpu_clk");
+	BUG_ON(IS_ERR(drv_state.ebi1_clk));
+
+	mutex_init(&drv_state.lock);
+	select_freq_plan(pvs_voltage);
+	acpuclk_8625q_data.wait_for_irq_khz = find_wait_for_irq_khz();
+
+	if (acpuclk_hw_init() < 0)
+		pr_err("acpuclk_hw_init not successful.\n");
+
+	print_acpu_freq_tbl();
+	lpj_init();
+	acpuclk_register(&acpuclk_8625q_data);
+
+	cpufreq_table_init();
+
+	return 0;
+}
+
+static struct platform_driver acpuclk_8625q_driver = {
+	.probe = acpuclk_8625q_probe,
+	.driver = {
+		.name = "acpuclock-8625q",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init acpuclk_8625q_init(void)
+{
+
+	return platform_driver_register(&acpuclk_8625q_driver);
+}
+postcore_initcall(acpuclk_8625q_init);
diff --git a/arch/arm/mach-msm/acpuclock-8625q.h b/arch/arm/mach-msm/acpuclock-8625q.h
new file mode 100644
index 0000000..ca2058f
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-8625q.h
@@ -0,0 +1,28 @@
+/*
+ * MSM architecture CPU clock driver header
+ *
+ * Copyright (c) 2012, 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
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __ARCH_ARM_MACH_MSM_ACPUCLOCK_8625Q_H
+#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_8625Q_H
+
+# include "acpuclock.h"
+/**
+ * struct acpuclk_pdata_8625q - Platform data for acpuclk
+ */
+struct acpuclk_pdata_8625q {
+	struct acpuclk_pdata *acpu_clk_data;
+	unsigned int pvs_voltage_uv;
+};
+
+#endif /* __ARCH_ARM_MACH_MSM_ACPUCLOCK_8625Q_H */
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index f70e41a..ed03e46 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2719,6 +2719,11 @@
 	.id	= -1,
 };
 
+static struct platform_device sp_input_loopback_pdev = {
+	.name	= "sp-user-input",
+	.id	= -1,
+};
+
 static int rf4ce_gpio_init(void)
 {
 	if (!machine_is_mpq8064_cdp() &&
@@ -2800,6 +2805,7 @@
 #endif
 	&rc_input_loopback_pdev,
 	&mpq8064_device_qup_spi_gsbi6,
+	&sp_input_loopback_pdev,
 };
 
 static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 7a2e9e1..3853e4c 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -15,6 +15,7 @@
 #include <linux/gpio.h>
 #include <mach/camera.h>
 #include <mach/msm_bus_board.h>
+#include <mach/socinfo.h>
 #include <mach/gpiomux.h>
 #include "devices.h"
 #include "board-8960.h"
@@ -182,6 +183,23 @@
 	},
 };
 
+static struct msm_gpiomux_config msm8960_cam_2d_configs_sglte[] = {
+	{
+		.gpio = 20,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 21,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+};
+
 #define VFE_CAMIF_TIMER1_GPIO 2
 #define VFE_CAMIF_TIMER2_GPIO 3
 #define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -828,6 +846,16 @@
 
 void __init msm8960_init_cam(void)
 {
+	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
+		msm_8960_front_cam_gpio_conf.cam_gpiomux_conf_tbl =
+			msm8960_cam_2d_configs_sglte;
+		msm_8960_front_cam_gpio_conf.cam_gpiomux_conf_tbl_size =
+			ARRAY_SIZE(msm8960_cam_2d_configs_sglte);
+		msm_8960_back_cam_gpio_conf.cam_gpiomux_conf_tbl =
+			msm8960_cam_2d_configs_sglte;
+		msm_8960_back_cam_gpio_conf.cam_gpiomux_conf_tbl_size =
+			ARRAY_SIZE(msm8960_cam_2d_configs_sglte);
+	}
 	msm_gpiomux_install(msm8960_cam_common_configs,
 			ARRAY_SIZE(msm8960_cam_common_configs));
 
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 0f6c000..28d50cc 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -68,6 +68,12 @@
 };
 #endif
 
+static struct gpiomux_setting gpio_epm_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv  = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
 static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv  = GPIOMUX_DRV_2MA,
@@ -411,6 +417,12 @@
 			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
 		},
 	},
+	{
+		.gpio      = 81,		/* EPM enable */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_epm_config,
+		},
+	},
 };
 
 static struct msm_gpiomux_config msm8974_slimbus_config[] __initdata = {
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 9fd5218..5cabe64 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -954,7 +954,7 @@
 	}
 	rpc_adsp_pdev->prog = ADSP_RPC_PROG;
 
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		rpc_adsp_pdev->pdev = msm8625_device_adsp;
 	else
 		rpc_adsp_pdev->pdev = msm_adsp_device;
@@ -1031,7 +1031,7 @@
 {
 	msm7x27a_cfg_uart2dm_serial();
 	msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		msm8625_device_uart_dm1.dev.platform_data =
 			&msm_uart_dm1_pdata;
 	else
@@ -1040,7 +1040,7 @@
 
 static void __init msm7x27a_otg_gadget(void)
 {
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		msm_otg_pdata.swfi_latency =
 		msm8625_pm_data[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].latency;
 		msm8625_device_otg.dev.platform_data = &msm_otg_pdata;
@@ -1080,7 +1080,7 @@
 	/* Initialize regulators first so that other devices can use them */
 	msm7x27a_init_regulators();
 	msm_adsp_add_pdev();
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		msm8625_device_i2c_init();
 	else
 		msm7x27a_device_i2c_init();
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 47a3120..d15b67d 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -933,7 +933,7 @@
 	}
 	rpc_adsp_pdev->prog = ADSP_RPC_PROG;
 
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		rpc_adsp_pdev->pdev = msm8625_device_adsp;
 	else
 		rpc_adsp_pdev->pdev = msm_adsp_device;
@@ -1041,7 +1041,7 @@
 static void __init qrd7627a_uart1dm_config(void)
 {
 	msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		msm8625_device_uart_dm1.dev.platform_data =
 			&msm_uart_dm1_pdata;
 	else
@@ -1050,7 +1050,7 @@
 
 static void __init qrd7627a_otg_gadget(void)
 {
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		msm_otg_pdata.swfi_latency = msm8625_pm_data
 		[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT].latency;
 		msm8625_device_otg.dev.platform_data = &msm_otg_pdata;
@@ -1069,7 +1069,7 @@
 static void __init msm_pm_init(void)
 {
 
-	if (!cpu_is_msm8625()) {
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q()) {
 		msm_pm_set_platform_data(msm7627a_pm_data,
 				ARRAY_SIZE(msm7627a_pm_data));
 		BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
@@ -1088,7 +1088,7 @@
 	msm7627a_init_regulators();
 	msmqrd_adsp_add_pdev();
 
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		msm8625_device_i2c_init();
 	else
 		msm7627a_device_i2c_init();
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 95f9327..445fc47 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -666,7 +666,8 @@
 #define A1_ID		 4
 #define A2_ID		 5
 #define DIFF_CLK_ID	 7
-#define DIV_CLK_ID	11
+#define DIV_CLK1_ID	11
+#define DIV_CLK2_ID	12
 
 DEFINE_CLK_RPM_SMD(pnoc_clk, pnoc_a_clk, RPM_BUS_CLK_TYPE, PNOC_ID, NULL);
 DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_ID, NULL);
@@ -689,7 +690,8 @@
 DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a0, cxo_a0_a, A0_ID);
 DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a1, cxo_a1_a, A1_ID);
 DEFINE_CLK_RPM_SMD_XO_BUFFER(cxo_a2, cxo_a2_a, A2_ID);
-DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk, div_a_clk, DIV_CLK_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk1, div_a_clk1, DIV_CLK1_ID);
+DEFINE_CLK_RPM_SMD_XO_BUFFER(div_clk2, div_a_clk2, DIV_CLK2_ID);
 DEFINE_CLK_RPM_SMD_XO_BUFFER(diff_clk, diff_a_clk, DIFF_CLK_ID);
 
 DEFINE_CLK_RPM_SMD_XO_BUFFER_PINCTRL(cxo_d0_pin, cxo_d0_a_pin, D0_ID);
@@ -5129,6 +5131,7 @@
 	CLK_LOOKUP("phy_clk", gcc_usb_hsic_clk.c,	  "msm_hsic_host"),
 	CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c,  "msm_hsic_host"),
 	CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "msm_hsic_host"),
+	CLK_LOOKUP("ref_clk", div_clk2.c, "msm_smsc_hub"),
 
 	/* Multimedia clocks */
 	CLK_LOOKUP("bus_clk_src", axi_clk_src.c, ""),
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index e0d98b7..d862d6d 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -227,7 +227,7 @@
 	 * be changed independently. Each cpu is bound to
 	 * same frequency. Hence set the cpumask to all cpu.
 	 */
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		cpumask_setall(policy->cpus);
 
 	if (cpufreq_frequency_table_cpuinfo(policy, table)) {
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 8fc5020..b3d887e 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -515,7 +515,7 @@
 
 void __init msm_pm_register_irqs(void)
 {
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		msm_pm_set_irq_extns(&msm8625_pm_irq_calls);
 	else
 		msm_pm_set_irq_extns(&msm7x27a_pm_irq_calls);
@@ -530,8 +530,9 @@
 void __init msm_pm_register_cpr_ops(void)
 {
 	/* CPR presents on revision >= v2.0 chipsets */
-	if (cpu_is_msm8625() &&
+	if ((cpu_is_msm8625() &&
 			SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
+			|| cpu_is_msm8625q())
 		msm_pm_set_cpr_ops(&msm8625_pm_cpr_ops);
 }
 
@@ -952,7 +953,7 @@
 
 void __init msm8x25_kgsl_3d0_init(void)
 {
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		kgsl_3d0_pdata.idle_timeout = HZ/5;
 		kgsl_3d0_pdata.strtstp_sleepwake = false;
 
@@ -1406,7 +1407,7 @@
 	if (controller < 1 || controller > 4)
 		return -EINVAL;
 
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		pdev = msm8625_sdcc_devices[controller-1];
 	else
 		pdev = msm_sdcc_devices[controller-1];
@@ -1495,7 +1496,7 @@
 {
 	struct platform_device	*pdev;
 
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		pdev = msm8625_host_devices[host];
 	else
 		pdev = msm_host_devices[host];
@@ -1598,12 +1599,12 @@
 void __init msm_fb_register_device(char *name, void *data)
 {
 	if (!strncmp(name, "mdp", 3)) {
-		if (cpu_is_msm8625())
+		if (cpu_is_msm8625() || cpu_is_msm8625q())
 			msm_register_device(&msm8625_mdp_device, data);
 		else
 			msm_register_device(&msm_mdp_device, data);
 	} else if (!strncmp(name, "mipi_dsi", 8)) {
-		if (cpu_is_msm8625()) {
+		if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 			msm_register_device(&msm8625_mipi_dsi_device, data);
 			mipi_dsi_device = msm8625_mipi_dsi_device;
 		} else {
@@ -2046,7 +2047,7 @@
 	msm_clock_init(&msm7x27a_clock_init_data);
 	if (cpu_is_msm7x27aa() || cpu_is_msm7x25ab())
 		platform_device_register(&msm7x27aa_device_acpuclk);
-	else if (cpu_is_msm8625()) {
+	else if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		if (msm8625_cpu_id() == MSM8625)
 			platform_device_register(&msm7x27aa_device_acpuclk);
 		else if (msm8625_cpu_id() == MSM8625A)
@@ -2057,11 +2058,11 @@
 		platform_device_register(&msm7x27a_device_acpuclk);
 	}
 
-	if (cpu_is_msm8625() &&
-			(SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2))
+	if (cpu_is_msm8625() || (cpu_is_msm8625q() &&
+			SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2))
 		msm_cpr_init();
 
-	if (!cpu_is_msm8625())
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
 		pl310_resources[1].start = INT_L2CC_INTR;
 
 	platform_device_register(&pl310_erp_device);
@@ -2083,7 +2084,7 @@
 		   (0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | \
 		   (0x1 << L2X0_AUX_CTRL_EVNT_MON_BUS_EN_SHIFT);
 
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		/* Way Size 011(0x3) 64KB */
 		aux_ctrl |= (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | \
 			    (0x1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) | \
@@ -2099,7 +2100,7 @@
 	}
 
 	l2x0_init(MSM_L2CC_BASE, aux_ctrl, L2X0_AUX_CTRL_MASK);
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		pctrl = readl_relaxed(MSM_L2CC_BASE + L2X0_PREFETCH_CTRL);
 		pr_info("Prfetch Ctrl: 0x%08x\n", pctrl);
 	}
@@ -2136,7 +2137,7 @@
 
 static int msm7627a_init_gpio(void)
 {
-	if (cpu_is_msm8625())
+	if (cpu_is_msm8625() || cpu_is_msm8625q())
 		platform_device_register(&msm8625_device_gpio);
 	else
 		platform_device_register(&msm_device_gpio);
diff --git a/arch/arm/mach-msm/include/mach/msm_adsp.h b/arch/arm/mach-msm/include/mach/msm_adsp.h
index e40c07d..ea08f0c 100644
--- a/arch/arm/mach-msm/include/mach/msm_adsp.h
+++ b/arch/arm/mach-msm/include/mach/msm_adsp.h
@@ -39,6 +39,7 @@
 void msm_adsp_put(struct msm_adsp_module *module);
 int msm_adsp_enable(struct msm_adsp_module *module);
 int msm_adsp_disable(struct msm_adsp_module *module);
+int msm_adsp_dump(struct msm_adsp_module *module);
 int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate);
 int msm_adsp_disable_event_rsp(struct msm_adsp_module *module);
 int32_t get_adsp_resource(unsigned short client_idx,
diff --git a/arch/arm/mach-msm/lpm_resources.c b/arch/arm/mach-msm/lpm_resources.c
index c21ea33..5d7fc94 100644
--- a/arch/arm/mach-msm/lpm_resources.c
+++ b/arch/arm/mach-msm/lpm_resources.c
@@ -47,8 +47,6 @@
 static bool msm_lpm_get_rpm_notif = true;
 
 /*Macros*/
-#define VDD_DIG_ACTIVE		(5)
-#define VDD_MEM_ACTIVE		(1050000)
 #define MAX_RS_NAME		(16)
 #define MAX_RS_SIZE		(4)
 #define IS_RPM_CTL(rs) \
@@ -133,10 +131,6 @@
 	.flush = msm_lpm_flush_l2,
 	.notify = NULL,
 	.valid = false,
-	.rs_data = {
-		.value = MSM_LPM_L2_CACHE_ACTIVE,
-		.default_value = MSM_LPM_L2_CACHE_ACTIVE,
-	},
 	.ko_attr = RPMRS_ATTR(l2),
 };
 
@@ -147,10 +141,6 @@
 	.flush = msm_lpm_flush_vdd_dig,
 	.notify = msm_lpm_notify_vdd_dig,
 	.valid = false,
-	.rs_data = {
-		.value = VDD_DIG_ACTIVE,
-		.default_value = VDD_DIG_ACTIVE,
-	},
 	.ko_attr = RPMRS_ATTR(vdd_dig),
 };
 
@@ -161,10 +151,6 @@
 	.flush = msm_lpm_flush_vdd_mem,
 	.notify = msm_lpm_notify_vdd_mem,
 	.valid = false,
-	.rs_data = {
-		.value = VDD_MEM_ACTIVE,
-		.default_value = VDD_MEM_ACTIVE,
-	},
 	.ko_attr = RPMRS_ATTR(vdd_mem),
 };
 
@@ -175,10 +161,6 @@
 	.flush = msm_lpm_flush_pxo,
 	.notify = msm_lpm_notify_pxo,
 	.valid = false,
-	.rs_data = {
-		.value = MSM_LPM_PXO_ON,
-		.default_value = MSM_LPM_PXO_ON,
-	},
 	.ko_attr = RPMRS_ATTR(pxo),
 };
 
@@ -421,13 +403,13 @@
 	trace_lpm_resources(rs->sleep_value, rs->name);
 }
 
-static void msm_lpm_flush_l2(int notify_rpm)
+static void msm_lpm_set_l2_mode(int sleep_mode, int notify_rpm)
 {
-	struct msm_lpm_resource *rs = &msm_lpm_l2;
-	int lpm;
-	int rc;
+	int lpm, rc;
 
-	switch (rs->sleep_value) {
+	msm_pm_set_l2_flush_flag(0);
+
+	switch (sleep_mode) {
 	case MSM_LPM_L2_CACHE_HSFS_OPEN:
 		lpm = MSM_SPM_L2_MODE_POWER_COLLAPSE;
 		msm_pm_set_l2_flush_flag(1);
@@ -455,6 +437,13 @@
 				__func__, lpm);
 }
 
+static void msm_lpm_flush_l2(int notify_rpm)
+{
+	struct msm_lpm_resource *rs = &msm_lpm_l2;
+
+	msm_lpm_set_l2_mode(rs->sleep_value, notify_rpm);
+}
+
 /* RPM CTL */
 static void msm_lpm_flush_rpm_ctl(int notify_rpm)
 {
@@ -679,8 +668,7 @@
 	}
 	msm_lpm_get_rpm_notif = true;
 
-	if (msm_lpm_use_mpm(limits))
-		msm_mpm_enter_sleep(sclk_count, from_idle);
+	msm_mpm_enter_sleep(sclk_count, from_idle);
 
 	return ret;
 }
@@ -688,11 +676,11 @@
 void msm_lpmrs_exit_sleep(struct msm_rpmrs_limits *limits,
 		bool from_idle, bool notify_rpm, bool collapsed)
 {
-	/* MPM exit sleep
 	if (msm_lpm_use_mpm(limits))
-		msm_mpm_exit_sleep(from_idle);*/
+		msm_mpm_exit_sleep(from_idle);
 
-	msm_spm_l2_set_low_power_mode(MSM_SPM_MODE_DISABLED, notify_rpm);
+	if (msm_lpm_l2.valid)
+		msm_lpm_set_l2_mode(msm_lpm_l2.rs_data.default_value, false);
 }
 
 static int msm_lpm_cpu_callback(struct notifier_block *cpu_nb,
@@ -702,12 +690,12 @@
 	switch (action) {
 	case CPU_UP_PREPARE:
 	case CPU_UP_PREPARE_FROZEN:
-		rs->rs_data.value = MSM_LPM_L2_CACHE_ACTIVE;
+		rs->rs_data.value = rs->rs_data.default_value;
 		break;
 	case CPU_ONLINE_FROZEN:
 	case CPU_ONLINE:
 		if (num_online_cpus() > 1)
-			rs->rs_data.value = MSM_LPM_L2_CACHE_ACTIVE;
+			rs->rs_data.value = rs->rs_data.default_value;
 		break;
 	case CPU_DEAD_FROZEN:
 	case CPU_DEAD:
@@ -825,6 +813,16 @@
 			continue;
 		}
 
+		key = "qcom,init-value";
+		ret = of_property_read_u32(node, key,
+				&rs->rs_data.default_value);
+		if (ret) {
+			pr_err("%s():Failed to read %s\n", __func__, key);
+			goto fail;
+		}
+
+		rs->rs_data.value = rs->rs_data.default_value;
+
 		key = "qcom,resource-type";
 		ret = of_property_read_u32(node, key, &resource_type);
 		if (ret) {
diff --git a/arch/arm/mach-msm/msm-buspm-dev.c b/arch/arm/mach-msm/msm-buspm-dev.c
index a818eed..ec0f1bd 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.c
+++ b/arch/arm/mach-msm/msm-buspm-dev.c
@@ -22,10 +22,17 @@
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
 #include <linux/memory_alloc.h>
+#include <mach/rpm-smd.h>
 #include "msm-buspm-dev.h"
 
 #define MSM_BUSPM_DRV_NAME "msm-buspm-dev"
 
+enum msm_buspm_spdm_res {
+	SPDM_RES_ID = 0,
+	SPDM_RES_TYPE = 0x63707362,
+	SPDM_KEY = 0x00006e65,
+	SPDM_SIZE = 4,
+};
 /*
  * Allocate kernel buffer.
  * Currently limited to one buffer per file descriptor.  If alloc() is
@@ -113,6 +120,61 @@
 	return 0;
 }
 
+static int msm_bus_rpm_req(u32 rsc_type, u32 key, u32 hwid,
+	int ctx, u32 val)
+{
+	struct msm_rpm_request *rpm_req;
+	int ret, msg_id;
+
+	rpm_req = msm_rpm_create_request(ctx, rsc_type, SPDM_RES_ID, 1);
+	if (rpm_req == NULL) {
+		pr_err("RPM: Couldn't create RPM Request\n");
+		return -ENXIO;
+	}
+
+	ret = msm_rpm_add_kvp_data(rpm_req, key, (const uint8_t *)&val,
+		(int)(sizeof(uint32_t)));
+	if (ret) {
+		pr_err("RPM: Add KVP failed for RPM Req:%u\n",
+			rsc_type);
+		goto err;
+	}
+
+	pr_debug("Added Key: %d, Val: %u, size: %d\n", key,
+		(uint32_t)val, sizeof(uint32_t));
+	msg_id = msm_rpm_send_request(rpm_req);
+	if (!msg_id) {
+		pr_err("RPM: No message ID for req\n");
+		ret = -ENXIO;
+		goto err;
+	}
+
+	ret = msm_rpm_wait_for_ack(msg_id);
+	if (ret) {
+		pr_err("RPM: Ack failed\n");
+		goto err;
+	}
+
+err:
+	msm_rpm_free_request(rpm_req);
+	return ret;
+}
+
+static int msm_buspm_ioc_cmds(uint32_t arg)
+{
+	switch (arg) {
+	case MSM_BUSPM_SPDM_CLK_DIS:
+	case MSM_BUSPM_SPDM_CLK_EN:
+		return msm_bus_rpm_req(SPDM_RES_TYPE, SPDM_KEY, 0,
+				MSM_RPM_CTX_ACTIVE_SET, arg);
+	default:
+		pr_warn("Unsupported ioctl command: %d\n", arg);
+		return -EINVAL;
+	}
+}
+
+
+
 static long
 msm_buspm_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
@@ -124,6 +186,11 @@
 	unsigned int buflen = msm_buspm_dev_get_buflen(filp);
 	unsigned char *dbgbuf = buf;
 
+	if (_IOC_TYPE(cmd) != MSM_BUSPM_IOC_MAGIC) {
+		pr_err("Wrong IOC_MAGIC.Exiting\n");
+		return -ENOTTY;
+	}
+
 	switch (cmd) {
 	case MSM_BUSPM_IOC_FREE:
 		pr_debug("cmd = 0x%x (FREE)\n", cmd);
@@ -193,6 +260,11 @@
 		}
 		break;
 
+	case MSM_BUSPM_IOC_CMD:
+		pr_debug("IOCTL command: cmd: %d arg: %lu\n", cmd, arg);
+		retval = msm_buspm_ioc_cmds(arg);
+		break;
+
 	default:
 		pr_debug("Unknown command 0x%x\n", cmd);
 		retval = -EINVAL;
diff --git a/arch/arm/mach-msm/msm-buspm-dev.h b/arch/arm/mach-msm/msm-buspm-dev.h
index 5839087..854626d 100644
--- a/arch/arm/mach-msm/msm-buspm-dev.h
+++ b/arch/arm/mach-msm/msm-buspm-dev.h
@@ -31,6 +31,11 @@
 	int size;
 };
 
+enum msm_buspm_ioc_cmds {
+	MSM_BUSPM_SPDM_CLK_DIS = 0,
+	MSM_BUSPM_SPDM_CLK_EN,
+};
+
 #define MSM_BUSPM_IOC_MAGIC	'p'
 
 #define MSM_BUSPM_IOC_FREE	\
@@ -47,4 +52,7 @@
 
 #define MSM_BUSPM_IOC_RD_PHYS_ADDR	\
 	_IOR(MSM_BUSPM_IOC_MAGIC, 4, unsigned long)
+
+#define MSM_BUSPM_IOC_CMD	\
+	_IOR(MSM_BUSPM_IOC_MAGIC, 5, uint32_t)
 #endif
diff --git a/arch/arm/mach-msm/msm7k_fiq.c b/arch/arm/mach-msm/msm7k_fiq.c
index 421b4f9..d644121 100644
--- a/arch/arm/mach-msm/msm7k_fiq.c
+++ b/arch/arm/mach-msm/msm7k_fiq.c
@@ -75,7 +75,7 @@
 
 static int __init init7k_fiq(void)
 {
-	if (!cpu_is_msm8625())
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
 		return 0;
 
 	if (msm_setup_fiq_handler())
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index 65539c6..e61eb6d 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -614,6 +614,15 @@
 			MSM_BUS_DBG("ab: %llu ib: %llu\n", curr_bw, curr_clk);
 		}
 
+		if (index == 0) {
+			/* This check protects the bus driver from clients
+			 * that can leave non-zero requests after
+			 * unregistering.
+			 * */
+			req_clk = 0;
+			req_bw = 0;
+		}
+
 		if (!pdata->active_only) {
 			ret = update_path(src, pnode, req_clk, req_bw,
 				curr_clk, curr_bw, 0, pdata->active_only);
diff --git a/arch/arm/mach-msm/ocmem_rdm.c b/arch/arm/mach-msm/ocmem_rdm.c
index 818a20a..8962729 100644
--- a/arch/arm/mach-msm/ocmem_rdm.c
+++ b/arch/arm/mach-msm/ocmem_rdm.c
@@ -191,6 +191,7 @@
 	int table_end = 0;
 	int br_ctrl = 0;
 	int br_id = 0;
+	int client_id = 0;
 	int dm_ctrl = 0;
 	int i = 0;
 	int j = 0;
@@ -244,6 +245,8 @@
 	dm_ctrl |= (table_start << DM_TBL_START);
 	dm_ctrl |= (table_end << DM_TBL_END);
 
+	client_id = client_ctrl_id(id);
+	dm_ctrl |= (client_id << DM_CLIENT_SHIFT);
 	dm_ctrl |= (DM_BR_ID_LPASS << DM_BR_ID_SHIFT);
 	dm_ctrl |= (DM_BLOCK_256 << DM_BR_BLK_SHIFT);
 	dm_ctrl |= (direction << DM_DIR_SHIFT);
diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
index 103eef0..26c5e58 100644
--- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
@@ -72,9 +72,11 @@
  */
 struct pmu_constraints {
 	u64 pmu_bitmap;
+	u8 codes[64];
 	raw_spinlock_t lock;
 } l2_pmu_constraints = {
 	.pmu_bitmap = 0,
+	.codes = {-1},
 	.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
 };
 
@@ -335,8 +337,10 @@
 	int ctr = 0;
 
 	if (hwc->config_base == L2CYCLE_CTR_RAW_CODE) {
-		if (!test_and_set_bit(l2_cycle_ctr_idx, cpuc->used_mask))
-			return l2_cycle_ctr_idx;
+		if (test_and_set_bit(l2_cycle_ctr_idx, cpuc->used_mask))
+			return -EAGAIN;
+
+		return l2_cycle_ctr_idx;
 	}
 
 	for (ctr = 0; ctr < total_l2_ctrs - 1; ctr++) {
@@ -453,22 +457,48 @@
 {
 	u32 evt_type = event->attr.config & L2_EVT_MASK;
 	u8 reg   = (evt_type & 0x0F000) >> 12;
-	u8 group =  evt_type & 0x0000F;
+	u8 group = evt_type & 0x0000F;
+	u8 code = (evt_type & 0x00FF0) >> 4;
 	unsigned long flags;
 	u32 err = 0;
 	u64 bitmap_t;
+	u32 shift_idx;
+
+	/*
+	 * Cycle counter collision is detected in
+	 * get_event_idx().
+	 */
+	if (evt_type == L2CYCLE_CTR_RAW_CODE)
+		return err;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
 		l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+		l2_pmu_constraints.codes[shift_idx] = code;
 		goto out;
+	} else {
+		/*
+		 * If NRCCG's are identical,
+		 * its not column exclusion.
+		 */
+		if (l2_pmu_constraints.codes[shift_idx] != code)
+			err = -EPERM;
+		else
+			/*
+			 * If the event is counted in syswide mode
+			 * then we want to count only on one CPU
+			 * and set its filter to count from all.
+			 * This sets the event OFF on all but one
+			 * CPU.
+			 */
+			if (!(event->cpu < 0))
+				event->state = PERF_EVENT_STATE_OFF;
 	}
-
-	/* Bit is already set. Constraint failed. */
-	err = -EPERM;
 out:
 	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
 	return err;
@@ -481,14 +511,20 @@
 	u8 group =  evt_type & 0x0000F;
 	unsigned long flags;
 	u64 bitmap_t;
+	u32 shift_idx;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	/* Clear constraint bit. */
 	l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
 
+	/* Clear code. */
+	l2_pmu_constraints.codes[shift_idx] = -1;
+
 	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
 	return 1;
 }
diff --git a/arch/arm/mach-msm/perf_event_msm_l2.c b/arch/arm/mach-msm/perf_event_msm_l2.c
index 2ad36df..c1b7d23 100644
--- a/arch/arm/mach-msm/perf_event_msm_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_l2.c
@@ -38,9 +38,11 @@
  */
 struct pmu_constraints {
 	u64 pmu_bitmap;
+	u8 codes[64];
 	raw_spinlock_t lock;
 } l2_pmu_constraints = {
 	.pmu_bitmap = 0,
+	.codes = {-1},
 	.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
 };
 
@@ -667,9 +669,11 @@
 	int ctr = 0;
 
 	if (hwc->config_base == SCORPION_L2CYCLE_CTR_RAW_CODE) {
-		if (!test_and_set_bit(l2_cycle_ctr_idx,
+		if (test_and_set_bit(l2_cycle_ctr_idx,
 					cpuc->used_mask))
-			return l2_cycle_ctr_idx;
+			return -EAGAIN;
+
+		return l2_cycle_ctr_idx;
 	}
 
 	for (ctr = 0; ctr < total_l2_ctrs - 1; ctr++) {
@@ -792,25 +796,50 @@
 	u8 prefix = (evt_type & 0xF0000) >> 16;
 	u8 reg   = (evt_type & 0x0F000) >> 12;
 	u8 group =  evt_type & 0x0000F;
+	u8 code = (evt_type & 0x00FF0) >> 4;
 	unsigned long flags;
 	u32 err = 0;
 	u64 bitmap_t;
+	u32 shift_idx;
 
 	if (!prefix)
 		return 0;
+	/*
+	 * Cycle counter collision is detected in
+	 * get_event_idx().
+	 */
+	if (evt_type == SCORPION_L2CYCLE_CTR_RAW_CODE)
+		return err;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
 		l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+		l2_pmu_constraints.codes[shift_idx] = code;
 		goto out;
+	} else {
+		/*
+		 * If NRCCG's are identical,
+		 * its not column exclusion.
+		 */
+		if (l2_pmu_constraints.codes[shift_idx] != code)
+			err = -EPERM;
+		else
+			/*
+			 * If the event is counted in syswide mode
+			 * then we want to count only on one CPU
+			 * and set its filter to count from all.
+			 * This sets the event OFF on all but one
+			 * CPU.
+			 */
+			if (!(event->cpu < 0))
+				event->state = PERF_EVENT_STATE_OFF;
 	}
 
-	/* Bit is already set. Constraint failed. */
-	err = -EPERM;
-
 out:
 	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
 	return err;
@@ -824,13 +853,16 @@
 	u8 group =  evt_type & 0x0000F;
 	unsigned long flags;
 	u64 bitmap_t;
+	u32 shift_idx;
 
 	if (!prefix)
 		return 0;
 
 	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
 
-	bitmap_t = 1 << ((reg * 4) + group);
+	shift_idx = ((reg * 4) + group);
+
+	bitmap_t = 1 << shift_idx;
 
 	/* Clear constraint bit. */
 	l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index e3a3563..88aae81 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -28,17 +28,24 @@
 #include <linux/msm_ion.h>
 #include <linux/list.h>
 #include <linux/list_sort.h>
+#include <linux/idr.h>
 
 #include <asm/uaccess.h>
 #include <asm/setup.h>
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
+#include <mach/msm_iomap.h>
 
 #include "peripheral-loader.h"
+#include "ramdump.h"
 
 #define pil_err(desc, fmt, ...)						\
 	dev_err(desc->dev, "%s: " fmt, desc->name, ##__VA_ARGS__)
 #define pil_info(desc, fmt, ...)					\
 	dev_info(desc->dev, "%s: " fmt, desc->name, ##__VA_ARGS__)
 
+#define PIL_IMAGE_INFO_BASE	(MSM_IMEM_BASE + 0x94c)
+
 /**
  * proxy_timeout - Override for proxy vote timeouts
  * -1: Use driver-specified timeout
@@ -80,6 +87,18 @@
 };
 
 /**
+ * struct pil_image_info - information in IMEM about image and where it is loaded
+ * @name: name of image (may or may not be NULL terminated)
+ * @start: indicates physical address where image starts (little endian)
+ * @size: size of image (little endian)
+ */
+struct pil_image_info {
+	char name[8];
+	__le64 start;
+	__le32 size;
+} __attribute__((__packed__));
+
+/**
  * struct pil_priv - Private state for a pil_desc
  * @proxy: work item used to run the proxy unvoting routine
  * @wlock: wakelock to prevent suspend during pil_boot
@@ -110,8 +129,46 @@
 	phys_addr_t region_start;
 	phys_addr_t region_end;
 	struct ion_handle *region;
+	struct pil_image_info __iomem *info;
+	int id;
 };
 
+/**
+ * pil_do_ramdump() - Ramdump an image
+ * @desc: descriptor from pil_desc_init()
+ * @ramdump_dev: ramdump device returned from create_ramdump_device()
+ *
+ * Calls the ramdump API with a list of segments generated from the addresses
+ * that the descriptor corresponds to.
+ */
+int pil_do_ramdump(struct pil_desc *desc, void *ramdump_dev)
+{
+	struct pil_priv *priv = desc->priv;
+	struct pil_seg *seg;
+	int count = 0, ret;
+	struct ramdump_segment *ramdump_segs, *s;
+
+	list_for_each_entry(seg, &priv->segs, list)
+		count++;
+
+	ramdump_segs = kmalloc_array(count, sizeof(*ramdump_segs), GFP_KERNEL);
+	if (!ramdump_segs)
+		return -ENOMEM;
+
+	s = ramdump_segs;
+	list_for_each_entry(seg, &priv->segs, list) {
+		s->address = seg->paddr;
+		s->size = seg->sz;
+		s++;
+	}
+
+	ret = do_elf_ramdump(ramdump_dev, ramdump_segs, count);
+	kfree(ramdump_segs);
+
+	return ret;
+}
+EXPORT_SYMBOL(pil_do_ramdump);
+
 static struct ion_client *ion;
 
 /**
@@ -337,6 +394,10 @@
 		priv->base_addr = min_addr_n;
 	}
 
+	writeq(priv->region_start, &priv->info->start);
+	writel_relaxed(priv->region_end - priv->region_start,
+			&priv->info->size);
+
 	return ret;
 }
 
@@ -380,6 +441,9 @@
 	struct pil_priv *priv = desc->priv;
 	struct pil_seg *p, *tmp;
 
+	writeq(0, &priv->info->start);
+	writel_relaxed(0, &priv->info->size);
+
 	if (priv->region)
 		ion_free(ion, priv->region);
 	priv->region = NULL;
@@ -593,6 +657,8 @@
 }
 EXPORT_SYMBOL(pil_shutdown);
 
+static DEFINE_IDA(pil_ida);
+
 /**
  * pil_desc_init() - Initialize a pil descriptor
  * @desc: descriptor to intialize
@@ -605,6 +671,9 @@
 int pil_desc_init(struct pil_desc *desc)
 {
 	struct pil_priv *priv;
+	int id;
+	void __iomem *addr;
+	size_t len;
 
 	/* Ignore users who don't make any sense */
 	WARN(desc->ops->proxy_unvote && !desc->proxy_timeout,
@@ -619,6 +688,18 @@
 	desc->priv = priv;
 	priv->desc = desc;
 
+	priv->id = id = ida_simple_get(&pil_ida, 0, 10, GFP_KERNEL);
+	if (id < 0) {
+		kfree(priv);
+		return id;
+	}
+	addr = PIL_IMAGE_INFO_BASE + sizeof(struct pil_image_info) * id;
+	priv->info = (struct pil_image_info __iomem *)addr;
+
+	len = min(strlen(desc->name), sizeof(priv->info->name));
+	memset_io(priv->info->name, 0, sizeof(priv->info->name));
+	memcpy_toio(priv->info->name, desc->name, len);
+
 	snprintf(priv->wname, sizeof(priv->wname), "pil-%s", desc->name);
 	wake_lock_init(&priv->wlock, WAKE_LOCK_SUSPEND, priv->wname);
 	INIT_DELAYED_WORK(&priv->proxy, pil_proxy_work);
@@ -637,6 +718,7 @@
 	struct pil_priv *priv = desc->priv;
 
 	if (priv) {
+		ida_simple_remove(&pil_ida, priv->id);
 		flush_delayed_work(&priv->proxy);
 		wake_lock_destroy(&priv->wlock);
 	}
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index 1c2faf7..8442289 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -65,6 +65,7 @@
 extern void pil_shutdown(struct pil_desc *desc);
 extern void pil_desc_release(struct pil_desc *desc);
 extern phys_addr_t pil_get_entry_addr(struct pil_desc *desc);
+extern int pil_do_ramdump(struct pil_desc *desc, void *ramdump_dev);
 #else
 static inline int pil_desc_init(struct pil_desc *desc) { return 0; }
 static inline int pil_boot(struct pil_desc *desc) { return 0; }
@@ -74,6 +75,10 @@
 {
 	return 0;
 }
+static inline int pil_do_ramdump(struct pil_desc *desc, void *ramdump_dev)
+{
+	return 0;
+}
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/pil-dsps.c b/arch/arm/mach-msm/pil-dsps.c
index 519e1c9..d315d82 100644
--- a/arch/arm/mach-msm/pil-dsps.c
+++ b/arch/arm/mach-msm/pil-dsps.c
@@ -48,7 +48,6 @@
 	void __iomem *ppss_base;
 
 	void *ramdump_dev;
-	struct ramdump_segment fw_ramdump_segments[4];
 
 	void *smem_ramdump_dev;
 	struct ramdump_segment smem_ramdump_segments[1];
@@ -212,16 +211,13 @@
 	if (!enable)
 		return 0;
 
-	ret = do_ramdump(drv->ramdump_dev,
-		drv->fw_ramdump_segments,
-		ARRAY_SIZE(drv->fw_ramdump_segments));
+	ret = pil_do_ramdump(&drv->desc, drv->ramdump_dev);
 	if (ret < 0) {
 		pr_err("%s: Unable to dump DSPS memory (rc = %d).\n",
 		       __func__, ret);
 		return ret;
 	}
-	ret = do_ramdump(drv->smem_ramdump_dev,
-		drv->smem_ramdump_segments,
+	ret = do_elf_ramdump(drv->smem_ramdump_dev, drv->smem_ramdump_segments,
 		ARRAY_SIZE(drv->smem_ramdump_segments));
 	if (ret < 0) {
 		pr_err("%s: Unable to dump smem memory (rc = %d).\n",
@@ -293,14 +289,6 @@
 	if (ret)
 		return ret;
 
-	drv->fw_ramdump_segments[0].address = 0x12000000;
-	drv->fw_ramdump_segments[0].size = 0x28000;
-	drv->fw_ramdump_segments[1].address = 0x12040000;
-	drv->fw_ramdump_segments[1].size = 0x4000;
-	drv->fw_ramdump_segments[2].address = 0x12800000;
-	drv->fw_ramdump_segments[2].size = 0x4000;
-	drv->fw_ramdump_segments[3].address = 0x8fe00000;
-	drv->fw_ramdump_segments[3].size = 0x100000;
 	drv->ramdump_dev = create_ramdump_device("dsps", &pdev->dev);
 	if (!drv->ramdump_dev) {
 		ret = -ENOMEM;
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index a6d13d0..f4d4449 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -404,11 +404,6 @@
 	smsm_reset_modem(SMSM_RESET);
 }
 
-/* FIXME: Get address, size from PIL */
-static struct ramdump_segment gss_segments[] = {
-	{0x89000000, 0x00D00000}
-};
-
 static struct ramdump_segment smem_segments[] = {
 	{0x80000000, 0x00200000},
 };
@@ -418,20 +413,20 @@
 	int ret;
 	struct gss_data *drv = container_of(desc, struct gss_data, subsys_desc);
 
-	if (enable) {
-		ret = do_ramdump(drv->ramdump_dev, gss_segments,
-				ARRAY_SIZE(gss_segments));
-		if (ret < 0) {
-			pr_err("Unable to dump gss memory\n");
-			return ret;
-		}
+	if (!enable)
+		return 0;
 
-		ret = do_ramdump(drv->smem_ramdump_dev, smem_segments,
-			ARRAY_SIZE(smem_segments));
-		if (ret < 0) {
-			pr_err("Unable to dump smem memory (rc = %d).\n", ret);
-			return ret;
-		}
+	ret = pil_do_ramdump(&drv->pil_desc, drv->ramdump_dev);
+	if (ret < 0) {
+		pr_err("Unable to dump gss memory\n");
+		return ret;
+	}
+
+	ret = do_elf_ramdump(drv->smem_ramdump_dev, smem_segments,
+		ARRAY_SIZE(smem_segments));
+	if (ret < 0) {
+		pr_err("Unable to dump smem memory (rc = %d).\n", ret);
+		return ret;
 	}
 
 	return 0;
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index d3c832b..3546705 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -393,21 +393,15 @@
 	return ret;
 }
 
-/* FIXME: Get address, size from PIL */
-static struct ramdump_segment modem_segments[] = {
-	{ 0x42F00000, 0x46000000 - 0x42F00000 },
-};
-
 static int modem_ramdump(int enable, const struct subsys_desc *subsys)
 {
 	struct modem_data *drv;
 
 	drv = container_of(subsys, struct modem_data, subsys_desc);
-	if (enable)
-		return do_ramdump(drv->ramdump_dev, modem_segments,
-				ARRAY_SIZE(modem_segments));
-	else
+	if (!enable)
 		return 0;
+
+	return pil_do_ramdump(&drv->pil_desc, drv->ramdump_dev);
 }
 
 static int __devinit pil_modem_driver_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index 162a7f7..b457599 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -385,19 +385,14 @@
 		smsm_change_state(SMSM_APPS_STATE, SMSM_RESET, SMSM_RESET);
 }
 
-static struct ramdump_segment pronto_segments[] = {
-	{ 0x0D200000, 0x0D980000 - 0x0D200000 }
-};
-
 static int wcnss_ramdump(int enable, const struct subsys_desc *subsys)
 {
 	struct pronto_data *drv = subsys_to_drv(subsys);
 
-	if (enable)
-		return do_ramdump(drv->ramdump_dev, pronto_segments,
-				ARRAY_SIZE(pronto_segments));
-	else
+	if (!enable)
 		return 0;
+
+	return pil_do_ramdump(&drv->desc, drv->ramdump_dev);
 }
 
 static int __devinit pil_pronto_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/pil-q6v3.c b/arch/arm/mach-msm/pil-q6v3.c
index d7e712c..1f53f17 100644
--- a/arch/arm/mach-msm/pil-q6v3.c
+++ b/arch/arm/mach-msm/pil-q6v3.c
@@ -279,22 +279,15 @@
 	return ret;
 }
 
-/* FIXME: Get address, size from PIL */
-static struct ramdump_segment q6_segments[] = {
-	{ 0x46700000, 0x47f00000 - 0x46700000 },
-	{ 0x28400000, 0x12800 }
-};
-
 static int lpass_q6_ramdump(int enable, const struct subsys_desc *subsys)
 {
 	struct q6v3_data *drv;
 
 	drv = container_of(subsys, struct q6v3_data, subsys_desc);
-	if (enable)
-		return do_ramdump(drv->ramdump_dev, q6_segments,
-				ARRAY_SIZE(q6_segments));
-	else
+	if (!enable)
 		return 0;
+
+	return pil_do_ramdump(&drv->pil_desc, drv->ramdump_dev);
 }
 
 static void lpass_q6_crash_shutdown(const struct subsys_desc *subsys)
diff --git a/arch/arm/mach-msm/pil-q6v4-lpass.c b/arch/arm/mach-msm/pil-q6v4-lpass.c
index 1e6c1f6..1387433 100644
--- a/arch/arm/mach-msm/pil-q6v4-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v4-lpass.c
@@ -231,18 +231,14 @@
 	return ret;
 }
 
-static struct ramdump_segment segments[] = {
-	{0x8da00000, 0x8f200000 - 0x8da00000},
-	{0x28400000, 0x20000}
-};
-
 static int lpass_ramdump(int enable, const struct subsys_desc *subsys)
 {
 	struct lpass_q6v4 *drv = subsys_to_lpass(subsys);
 
 	if (!enable)
 		return 0;
-	return do_ramdump(drv->ramdump_dev, segments, ARRAY_SIZE(segments));
+
+	return pil_do_ramdump(&drv->q6.desc, drv->ramdump_dev);
 }
 
 static void lpass_crash_shutdown(const struct subsys_desc *subsys)
diff --git a/arch/arm/mach-msm/pil-q6v4-mss.c b/arch/arm/mach-msm/pil-q6v4-mss.c
index ee01f04..f2b090f 100644
--- a/arch/arm/mach-msm/pil-q6v4-mss.c
+++ b/arch/arm/mach-msm/pil-q6v4-mss.c
@@ -243,14 +243,6 @@
 	smsm_reset_modem(SMSM_RESET);
 }
 
-static struct ramdump_segment sw_segments[] = {
-	{0x89000000, 0x8D400000 - 0x89000000},
-};
-
-static struct ramdump_segment fw_segments[] = {
-	{0x8D400000, 0x8DA00000 - 0x8D400000},
-};
-
 static struct ramdump_segment smem_segments[] = {
 	{0x80000000, 0x00200000},
 };
@@ -263,17 +255,15 @@
 	if (!enable)
 		return 0;
 
-	ret = do_ramdump(drv->sw_ramdump_dev, sw_segments,
-		ARRAY_SIZE(sw_segments));
+	ret = pil_do_ramdump(&drv->q6_sw.desc, drv->sw_ramdump_dev);
 	if (ret < 0)
 		return ret;
 
-	ret = do_ramdump(drv->fw_ramdump_dev, fw_segments,
-		ARRAY_SIZE(fw_segments));
+	ret = pil_do_ramdump(&drv->q6_fw.desc, drv->fw_ramdump_dev);
 	if (ret < 0)
 		return ret;
 
-	ret = do_ramdump(drv->smem_ramdump_dev, smem_segments,
+	ret = do_elf_ramdump(drv->smem_ramdump_dev, smem_segments,
 		ARRAY_SIZE(smem_segments));
 	if (ret < 0)
 		return ret;
diff --git a/arch/arm/mach-msm/pil-q6v5-lpass.c b/arch/arm/mach-msm/pil-q6v5-lpass.c
index 662377d..94632da 100644
--- a/arch/arm/mach-msm/pil-q6v5-lpass.c
+++ b/arch/arm/mach-msm/pil-q6v5-lpass.c
@@ -307,15 +307,14 @@
 	return ret;
 }
 
-static struct ramdump_segment segments = { 0xdc00000, 0x1800000 };
-
 static int adsp_ramdump(int enable, const struct subsys_desc *subsys)
 {
 	struct lpass_data *drv = subsys_to_lpass(subsys);
 
 	if (!enable)
 		return 0;
-	return do_ramdump(drv->ramdump_dev, &segments, 1);
+
+	return pil_do_ramdump(&drv->q6->desc, drv->ramdump_dev);
 }
 
 static void adsp_crash_shutdown(const struct subsys_desc *subsys)
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index b8309e5..ed85c95 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -496,10 +496,6 @@
 	smsm_reset_modem(SMSM_RESET);
 }
 
-static struct ramdump_segment modem_segments[] = {
-	{0x08400000, 0x0D100000 - 0x08400000},
-};
-
 static struct ramdump_segment smem_segments[] = {
 	{0x0FA00000, 0x0FC00000 - 0x0FA00000},
 };
@@ -516,14 +512,13 @@
 	if (ret)
 		return ret;
 
-	ret = do_ramdump(drv->ramdump_dev, modem_segments,
-				ARRAY_SIZE(modem_segments));
+	ret = pil_do_ramdump(&drv->q6->desc, drv->ramdump_dev);
 	if (ret < 0) {
 		pr_err("Unable to dump modem fw memory (rc = %d).\n", ret);
 		goto out;
 	}
 
-	ret = do_ramdump(drv->smem_ramdump_dev, smem_segments,
+	ret = do_elf_ramdump(drv->smem_ramdump_dev, smem_segments,
 		ARRAY_SIZE(smem_segments));
 	if (ret < 0) {
 		pr_err("Unable to dump smem memory (rc = %d).\n", ret);
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 74fae98..96b9882 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -412,26 +412,16 @@
 	return ret;
 }
 
-/*
- * 7MB RAM segments for Riva SS;
- * Riva 1.1 0x8f000000 - 0x8f700000
- * Riva 1.0 0x8f200000 - 0x8f700000
- */
-static struct ramdump_segment riva_segments[] = {
-	{0x8f000000, 0x8f700000 - 0x8f000000}
-};
-
 static int riva_ramdump(int enable, const struct subsys_desc *desc)
 {
 	struct riva_data *drv;
 
 	drv = container_of(desc, struct riva_data, subsys_desc);
 
-	if (enable)
-		return do_ramdump(drv->ramdump_dev, riva_segments,
-				ARRAY_SIZE(riva_segments));
-	else
+	if (!enable)
 		return 0;
+
+	return pil_do_ramdump(&drv->pil_desc, drv->ramdump_dev);
 }
 
 /* Riva crash handler */
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index f32e149..53cc0f5 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -137,7 +137,7 @@
 			= msm_pm_config_rst_vector_after_pc;
 		break;
 	case MSM_PM_BOOT_CONFIG_REMAP_BOOT_ADDR:
-		if (!cpu_is_msm8625()) {
+		if (!cpu_is_msm8625() && !cpu_is_msm8625q()) {
 			void *remapped;
 
 			/*
@@ -200,7 +200,7 @@
 					pdata->v_addr + mpa5_cfg_ctl[0]);
 
 			/* 8x25Q changes */
-			if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 3) {
+			if (cpu_is_msm8625q()) {
 				/* write 'entry' to boot remapper register */
 				__raw_writel(entry, (pdata->v_addr +
 						mpa5_boot_remap_addr[1]));
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 96c1218..ec9f030 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -562,7 +562,7 @@
 		__raw_writel(0, APPS_PWRDOWN);
 		mb();
 		msm_spm_reinit();
-	} else if (cpu_is_msm8625()) {
+	} else if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		__raw_writel(0, APPS_PWRDOWN);
 		mb();
 
@@ -881,7 +881,7 @@
 
 	memset(msm_pm_smem_data, 0, sizeof(*msm_pm_smem_data));
 
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		/* Program the SPM */
 		ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE,
 									false);
@@ -971,7 +971,7 @@
 #endif
 
 #ifdef CONFIG_CACHE_L2X0
-	if (!cpu_is_msm8625())
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
 		l2cc_suspend();
 	else
 		apps_power_collapse = 1;
@@ -983,7 +983,7 @@
 	 * TBD: Currently recognise the MODEM early exit
 	 * path by reading the MPA5_GDFS_CNT_VAL register.
 	 */
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		int cpu;
 		/*
 		 * on system reset, default value of MPA5_GDFS_CNT_VAL
@@ -997,7 +997,7 @@
 		val = __raw_readl(MSM_CFG_CTL_BASE + 0x38);
 
 		/* 8x25Q */
-		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 3) {
+		if (cpu_is_msm8625q()) {
 			if (val != 0x000F0002) {
 				for_each_possible_cpu(cpu) {
 					if (!cpu)
@@ -1031,7 +1031,7 @@
 	}
 
 #ifdef CONFIG_CACHE_L2X0
-	if (!cpu_is_msm8625())
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
 		l2cc_resume();
 	else
 		apps_power_collapse = 0;
@@ -1153,7 +1153,7 @@
 
 	smd_sleep_exit();
 
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING,
 									false);
 		WARN_ON(ret);
@@ -1220,7 +1220,7 @@
 		msm_cpr_ops->cpr_resume();
 
 power_collapse_bail:
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING,
 									false);
 		WARN_ON(ret);
@@ -1258,14 +1258,14 @@
 #endif
 
 #ifdef CONFIG_CACHE_L2X0
-	if (!cpu_is_msm8625())
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
 		l2cc_suspend();
 #endif
 
 	collapsed = msm_pm_collapse();
 
 #ifdef CONFIG_CACHE_L2X0
-	if (!cpu_is_msm8625())
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
 		l2cc_resume();
 #endif
 
@@ -1310,7 +1310,7 @@
 			return -EIO;
 	}
 
-	if (!cpu_is_msm8625())
+	if (!cpu_is_msm8625() && !cpu_is_msm8625q())
 		msm_pm_config_hw_before_swfi();
 
 	msm_arch_idle();
@@ -1713,7 +1713,7 @@
 		return ret;
 	}
 
-	if (cpu_is_msm8625()) {
+	if (cpu_is_msm8625() || cpu_is_msm8625q()) {
 		target_type = TARGET_IS_8625;
 		clean_caches((unsigned long)&target_type, sizeof(target_type),
 				virt_to_phys(&target_type));
@@ -1725,7 +1725,7 @@
 		 * MPA5_GDFS_CNT_VAL[9:0] = Delay counter for
 		 * GDFS control.
 		 */
-		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 3)
+		if (cpu_is_msm8625q())
 			val = 0x000F0002;
 		else
 			val = 0x00030002;
diff --git a/arch/arm/mach-msm/qdsp5/adsp.c b/arch/arm/mach-msm/qdsp5/adsp.c
index 6189da8..81af66b 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.c
+++ b/arch/arm/mach-msm/qdsp5/adsp.c
@@ -1080,6 +1080,21 @@
 	return 0;
 }
 
+int msm_adsp_dump(struct msm_adsp_module *module)
+{
+	int rc = 0;
+	if (!module) {
+		MM_INFO("Invalid module. Dumps are not collected\n");
+		return -EINVAL;
+	}
+	MM_INFO("starting DSP DUMP\n");
+	rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_CORE_DUMP,
+			module->id, module);
+	MM_INFO("DSP DUMP done rc =%d\n", rc);
+	return rc;
+}
+EXPORT_SYMBOL(msm_adsp_dump);
+
 int msm_adsp_enable(struct msm_adsp_module *module)
 {
 	int rc = 0;
@@ -1123,6 +1138,7 @@
 			rc = 0;
 		} else {
 			MM_ERR("module '%s' enable timed out\n", module->name);
+			msm_adsp_dump(module);
 			rc = -ETIMEDOUT;
 		}
 		if (module->open_count++ == 0 && module->clk)
diff --git a/arch/arm/mach-msm/qdsp5/adsp.h b/arch/arm/mach-msm/qdsp5/adsp.h
index 50f5b83..4e9d311 100644
--- a/arch/arm/mach-msm/qdsp5/adsp.h
+++ b/arch/arm/mach-msm/qdsp5/adsp.h
@@ -152,6 +152,7 @@
 	RPC_ADSP_RTOS_CMD_SET_STATE,
 	RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT,
 	RPC_ADSP_RTOS_CMD_GET_INIT_INFO,
+	RPC_ADSP_RTOS_CMD_CORE_DUMP,
 };
 
 enum rpc_adsp_rtos_mod_status_type {
diff --git a/arch/arm/mach-msm/qdsp5/audio_aac.c b/arch/arm/mach-msm/qdsp5/audio_aac.c
index 46a80d7..c36cac7 100644
--- a/arch/arm/mach-msm/qdsp5/audio_aac.c
+++ b/arch/arm/mach-msm/qdsp5/audio_aac.c
@@ -261,8 +261,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -306,8 +308,12 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
+
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_ac3.c b/arch/arm/mach-msm/qdsp5/audio_ac3.c
index e453ec5..b5337bd 100644
--- a/arch/arm/mach-msm/qdsp5/audio_ac3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_ac3.c
@@ -252,8 +252,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -296,8 +298,11 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrnb.c b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
index 0792e3f..4aa7403 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrnb.c
@@ -265,8 +265,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -310,8 +312,11 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_amrwb.c b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
index 7d37cea..57df4ad 100644
--- a/arch/arm/mach-msm/qdsp5/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_amrwb.c
@@ -262,8 +262,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -307,8 +309,11 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_evrc.c b/arch/arm/mach-msm/qdsp5/audio_evrc.c
index 155b0e1..0799ee1 100644
--- a/arch/arm/mach-msm/qdsp5/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5/audio_evrc.c
@@ -255,8 +255,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -299,8 +301,11 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index 8120d7b..e896e85 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -293,9 +293,10 @@
 	cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 	rc = audmgr_enable(&audio->audmgr, &cfg);
-	if (rc < 0)
+	if (rc < 0) {
+		msm_adsp_dump(audio->audplay);
 		return rc;
-
+	}
 	if (msm_adsp_enable(audio->audplay)) {
 		MM_ERR("msm_adsp_enable(audplay) failed\n");
 		audmgr_disable(&audio->audmgr);
@@ -335,7 +336,9 @@
 		wake_up(&audio->write_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		audmgr_disable(&audio->audmgr);
+		rc = audmgr_disable(&audio->audmgr);
+		if (rc < 0)
+			msm_adsp_dump(audio->audplay);
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_mp3.c b/arch/arm/mach-msm/qdsp5/audio_mp3.c
index b8c64be..a606bd5 100644
--- a/arch/arm/mach-msm/qdsp5/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5/audio_mp3.c
@@ -330,8 +330,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -376,8 +378,11 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm.c b/arch/arm/mach-msm/qdsp5/audio_pcm.c
index 3eb72c8..d19f80b 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm.c
@@ -299,9 +299,10 @@
 	cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 	rc = audmgr_enable(&audio->audmgr, &cfg);
-	if (rc < 0)
+	if (rc < 0) {
+		msm_adsp_dump(audio->audplay);
 		return rc;
-
+	}
 	if (msm_adsp_enable(audio->audplay)) {
 		MM_ERR("msm_adsp_enable(audplay) failed\n");
 		audmgr_disable(&audio->audmgr);
@@ -341,7 +342,9 @@
 		wake_up(&audio->write_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		audmgr_disable(&audio->audmgr);
+		rc = audmgr_disable(&audio->audmgr);
+		if (rc < 0)
+			msm_adsp_dump(audio->audplay);
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 68ffcfef..7b2090d 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -218,9 +218,10 @@
 	cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 	rc = audmgr_enable(&audio->audmgr, &cfg);
-	if (rc < 0)
+	if (rc < 0) {
+		msm_adsp_dump(audio->audrec);
 		return rc;
-
+	}
 	if (audpreproc_enable(audio->enc_id, &audpre_dsp_event, audio)) {
 		MM_ERR("msm_adsp_enable(audpreproc) failed\n");
 		audmgr_disable(&audio->audmgr);
@@ -249,6 +250,8 @@
 /* must be called with audio->lock held */
 static int audpcm_in_disable(struct audio_in *audio)
 {
+	int rc;
+
 	if (audio->enabled) {
 		audio->enabled = 0;
 
@@ -262,7 +265,9 @@
 		/*reset the sampling frequency information at audpreproc layer*/
 		audio->session_info.sampling_freq = 0;
 		audpreproc_update_audrec_info(&audio->session_info);
-		audmgr_disable(&audio->audmgr);
+		rc = audmgr_disable(&audio->audmgr);
+		if (rc < 0)
+			msm_adsp_dump(audio->audrec);
 	}
 	return 0;
 }
diff --git a/arch/arm/mach-msm/qdsp5/audio_qcelp.c b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
index 876c909..3fc489c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5/audio_qcelp.c
@@ -251,8 +251,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -296,8 +298,11 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wma.c b/arch/arm/mach-msm/qdsp5/audio_wma.c
index 6d520b4..f7d54cc 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wma.c
@@ -268,8 +268,10 @@
 		cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 		rc = audmgr_enable(&audio->audmgr, &cfg);
-		if (rc < 0)
+		if (rc < 0) {
+			msm_adsp_dump(audio->audplay);
 			return rc;
+		}
 	}
 
 	if (msm_adsp_enable(audio->audplay)) {
@@ -314,8 +316,11 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
-			audmgr_disable(&audio->audmgr);
+		if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
+			rc = audmgr_disable(&audio->audmgr);
+			if (rc < 0)
+				msm_adsp_dump(audio->audplay);
+		}
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_wmapro.c b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
index a08f3c9..8dba4a6 100644
--- a/arch/arm/mach-msm/qdsp5/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5/audio_wmapro.c
@@ -266,8 +266,10 @@
 	cfg.snd_method = RPC_SND_METHOD_MIDI;
 
 	rc = audmgr_enable(&audio->audmgr, &cfg);
-	if (rc < 0)
+	if (rc < 0) {
+		msm_adsp_dump(audio->audplay);
 		return rc;
+	}
 
 	if (msm_adsp_enable(audio->audplay)) {
 		MM_ERR("msm_adsp_enable(audplay) failed\n");
@@ -309,7 +311,10 @@
 		wake_up(&audio->read_wait);
 		msm_adsp_disable(audio->audplay);
 		audpp_disable(audio->dec_id, audio);
-		audmgr_disable(&audio->audmgr);
+		rc = audmgr_disable(&audio->audmgr);
+		if (rc < 0)
+			msm_adsp_dump(audio->audplay);
+
 		audio->out_needed = 0;
 		rmt_put_resource(audio);
 		audio->rmt_resource_released = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audpp.c b/arch/arm/mach-msm/qdsp5/audpp.c
index b4ead5c..b4b7338f 100644
--- a/arch/arm/mach-msm/qdsp5/audpp.c
+++ b/arch/arm/mach-msm/qdsp5/audpp.c
@@ -292,6 +292,7 @@
 			MM_INFO("ENABLE\n");
 			if (!audpp->enabled) {
 				audpp->enabled = 1;
+				wake_up(&audpp->event_wait);
 				audpp_broadcast(audpp, id, msg);
 			} else {
 				cid = msg[1];
@@ -344,6 +345,7 @@
 	struct audpp_state *audpp = &the_audpp_state;
 	uint16_t msg[8];
 	int res = 0;
+	int rc;
 
 	if (id < -1 || id > 4)
 		return -EINVAL;
@@ -374,6 +376,11 @@
 		LOG(EV_ENABLE, 2);
 		msm_adsp_enable(audpp->mod);
 		audpp_dsp_config(1);
+		rc = wait_event_timeout(audpp->event_wait,
+					(audpp->enabled == 1),
+					3 * HZ);
+		if (rc == 0)
+			msm_adsp_dump(audpp->mod);
 	} else {
 		if (audpp->enabled) {
 			msg[0] = AUDPP_MSG_ENA_ENA;
@@ -424,13 +431,17 @@
 		MM_DBG("disable\n");
 		LOG(EV_DISABLE, 2);
 		audpp_dsp_config(0);
-		rc = wait_event_interruptible(audpp->event_wait,
-				(audpp->enabled == 0));
+		rc = wait_event_timeout(audpp->event_wait,
+					(audpp->enabled == 0),
+					3 * HZ);
 		if (audpp->enabled == 0)
 			MM_INFO("Received CFG_MSG_DISABLE from ADSP\n");
-		else
+		else {
 			MM_ERR("Didn't receive CFG_MSG DISABLE \
 					message from ADSP\n");
+			if (rc == 0)
+				msm_adsp_dump(audpp->mod);
+		}
 		msm_adsp_disable(audpp->mod);
 		msm_adsp_put(audpp->mod);
 		audpp->mod = NULL;
diff --git a/arch/arm/mach-msm/ramdump.c b/arch/arm/mach-msm/ramdump.c
index e33ec48..aac49d0 100644
--- a/arch/arm/mach-msm/ramdump.c
+++ b/arch/arm/mach-msm/ramdump.c
@@ -11,14 +11,10 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/reboot.h>
 #include <linux/workqueue.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
 #include <linux/sched.h>
-#include <linux/stringify.h>
-#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
@@ -26,8 +22,8 @@
 #include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/uaccess.h>
-
-#include <asm-generic/poll.h>
+#include <linux/elf.h>
+#include <linux/wait.h>
 
 #include "ramdump.h"
 
@@ -46,6 +42,8 @@
 	wait_queue_head_t dump_wait_q;
 	int nsegments;
 	struct ramdump_segment *segments;
+	size_t elfcore_size;
+	char *elfcore_buf;
 };
 
 static int ramdump_open(struct inode *inode, struct file *filep)
@@ -107,13 +105,29 @@
 	size_t copy_size = 0;
 	int ret = 0;
 
-	if (rd_dev->data_ready == 0) {
-		pr_err("Ramdump(%s): Read when there's no dump available!",
-			rd_dev->name);
-		return -EPIPE;
+	if ((filep->f_flags & O_NONBLOCK) && !rd_dev->data_ready)
+		return -EAGAIN;
+
+	ret = wait_event_interruptible(rd_dev->dump_wait_q, rd_dev->data_ready);
+	if (ret)
+		return ret;
+
+	if (*pos < rd_dev->elfcore_size) {
+		copy_size = min(rd_dev->elfcore_size, count);
+
+		if (copy_to_user(buf, rd_dev->elfcore_buf, copy_size)) {
+			ret = -EFAULT;
+			goto ramdump_done;
+		}
+		*pos += copy_size;
+		count -= copy_size;
+		buf += copy_size;
+		if (count == 0)
+			return copy_size;
 	}
 
-	addr = offset_translate(*pos, rd_dev, &data_left);
+	addr = offset_translate(*pos - rd_dev->elfcore_size, rd_dev,
+				&data_left);
 
 	/* EOF check */
 	if (data_left == 0) {
@@ -174,7 +188,7 @@
 	return mask;
 }
 
-const struct file_operations ramdump_file_ops = {
+static const struct file_operations ramdump_file_ops = {
 	.open = ramdump_open,
 	.release = ramdump_release,
 	.read = ramdump_read,
@@ -234,11 +248,14 @@
 	kfree(rd_dev);
 }
 
-int do_ramdump(void *handle, struct ramdump_segment *segments,
-		int nsegments)
+static int _do_ramdump(void *handle, struct ramdump_segment *segments,
+		int nsegments, bool use_elf)
 {
 	int ret, i;
 	struct ramdump_device *rd_dev = (struct ramdump_device *)handle;
+	Elf32_Phdr *phdr;
+	Elf32_Ehdr *ehdr;
+	unsigned long offset;
 
 	if (!rd_dev->consumer_present) {
 		pr_err("Ramdump(%s): No consumers. Aborting..\n", rd_dev->name);
@@ -251,6 +268,38 @@
 	rd_dev->segments = segments;
 	rd_dev->nsegments = nsegments;
 
+	if (use_elf) {
+		rd_dev->elfcore_size = sizeof(*ehdr) +
+				       sizeof(*phdr) * nsegments;
+		ehdr = kzalloc(rd_dev->elfcore_size, GFP_KERNEL);
+		rd_dev->elfcore_buf = (char *)ehdr;
+		if (!rd_dev->elfcore_buf)
+			return -ENOMEM;
+
+		memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
+		ehdr->e_ident[EI_CLASS] = ELFCLASS32;
+		ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
+		ehdr->e_ident[EI_VERSION] = EV_CURRENT;
+		ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
+		ehdr->e_type = ET_CORE;
+		ehdr->e_version = EV_CURRENT;
+		ehdr->e_phoff = sizeof(*ehdr);
+		ehdr->e_ehsize = sizeof(*ehdr);
+		ehdr->e_phentsize = sizeof(*phdr);
+		ehdr->e_phnum = nsegments;
+
+		offset = rd_dev->elfcore_size;
+		phdr = (Elf32_Phdr *)(ehdr + 1);
+		for (i = 0; i < nsegments; i++, phdr++) {
+			phdr->p_type = PT_LOAD;
+			phdr->p_offset = offset;
+			phdr->p_vaddr = phdr->p_paddr = segments[i].address;
+			phdr->p_filesz = phdr->p_memsz = segments[i].size;
+			phdr->p_flags = PF_R | PF_W | PF_X;
+			offset += phdr->p_filesz;
+		}
+	}
+
 	rd_dev->data_ready = 1;
 	rd_dev->ramdump_status = -1;
 
@@ -271,5 +320,20 @@
 		ret = (rd_dev->ramdump_status == 0) ? 0 : -EPIPE;
 
 	rd_dev->data_ready = 0;
+	rd_dev->elfcore_size = 0;
+	kfree(rd_dev->elfcore_buf);
+	rd_dev->elfcore_buf = NULL;
 	return ret;
+
+}
+
+int do_ramdump(void *handle, struct ramdump_segment *segments, int nsegments)
+{
+	return _do_ramdump(handle, segments, nsegments, false);
+}
+
+int
+do_elf_ramdump(void *handle, struct ramdump_segment *segments, int nsegments)
+{
+	return _do_ramdump(handle, segments, nsegments, true);
 }
diff --git a/arch/arm/mach-msm/ramdump.h b/arch/arm/mach-msm/ramdump.h
index 3e5bfaf..5fb41ec 100644
--- a/arch/arm/mach-msm/ramdump.h
+++ b/arch/arm/mach-msm/ramdump.h
@@ -24,5 +24,7 @@
 void destroy_ramdump_device(void *dev);
 int do_ramdump(void *handle, struct ramdump_segment *segments,
 		int nsegments);
+int do_elf_ramdump(void *handle, struct ramdump_segment *segments,
+		int nsegments);
 
 #endif
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index b378d3b..e77a7ac 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -374,7 +374,7 @@
 	};
 
 	struct mode_of of_l2_modes[] = {
-		{"qcom,saw2-spm-cmd-ret", MSM_SPM_L2_MODE_RETENTION, 1},
+		{"qcom,saw2-spm-cmd-ret", MSM_SPM_L2_MODE_RETENTION, 0},
 		{"qcom,saw2-spm-cmd-gdhs", MSM_SPM_L2_MODE_GDHS, 1},
 		{"qcom,saw2-spm-cmd-pc", MSM_SPM_L2_MODE_POWER_COLLAPSE, 1},
 	};
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 212ad77..e360906 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1035,7 +1035,8 @@
 
 	if (cpu_is_msm7x01() || cpu_is_msm7x25() || cpu_is_msm7x27() ||
 	    cpu_is_msm7x25a() || cpu_is_msm7x27a() || cpu_is_msm7x25aa() ||
-	    cpu_is_msm7x27aa() || cpu_is_msm8625() || cpu_is_msm7x25ab()) {
+	    cpu_is_msm7x27aa() || cpu_is_msm8625() || cpu_is_msm7x25ab() ||
+	    cpu_is_msm8625q()) {
 		dgt->shift = MSM_DGT_SHIFT;
 		dgt->freq = 19200000 >> MSM_DGT_SHIFT;
 		dgt->clockevent.shift = 32 + MSM_DGT_SHIFT;
@@ -1045,7 +1046,7 @@
 		gpt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT
 			   |  MSM_CLOCK_FLAGS_ODD_MATCH_WRITE
 			   |  MSM_CLOCK_FLAGS_DELAYED_WRITE_POST;
-		if (cpu_is_msm8625())
+		if (cpu_is_msm8625() || cpu_is_msm8625q())
 			fixup_msm8625_timer();
 	} else if (cpu_is_qsd8x50()) {
 		dgt->freq = 4800000;
@@ -1134,8 +1135,8 @@
 
 		ce->irq = clock->irq;
 		if (cpu_is_msm8x60() || cpu_is_msm9615() || cpu_is_msm8625() ||
-		    soc_class_is_msm8960() || soc_class_is_apq8064() ||
-		    soc_class_is_msm8930()) {
+		    cpu_is_msm8625q() || soc_class_is_msm8960() ||
+		    soc_class_is_apq8064() || soc_class_is_msm8930()) {
 			clock->percpu_evt = alloc_percpu(struct clock_event_device *);
 			if (!clock->percpu_evt) {
 				pr_err("msm_timer_init: memory allocation "
diff --git a/block/blk-core.c b/block/blk-core.c
index 68d7158..fe1c7e0 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -297,13 +297,26 @@
  * Description:
  *    See @blk_run_queue. This variant must be called with the queue lock
  *    held and interrupts disabled.
+ *    Device driver will be notified of an urgent request
+ *    pending under the following conditions:
+ *    1. The driver and the current scheduler support urgent reques handling
+ *    2. There is an urgent request pending in the scheduler
+ *    3. There isn't already an urgent request in flight, meaning previously
+ *       notified urgent request completed (!q->notified_urgent)
  */
 void __blk_run_queue(struct request_queue *q)
 {
 	if (unlikely(blk_queue_stopped(q)))
 		return;
 
-	q->request_fn(q);
+	if (!q->notified_urgent &&
+		q->elevator->type->ops.elevator_is_urgent_fn &&
+		q->urgent_request_fn &&
+		q->elevator->type->ops.elevator_is_urgent_fn(q)) {
+		q->notified_urgent = true;
+		q->urgent_request_fn(q);
+	} else
+		q->request_fn(q);
 }
 EXPORT_SYMBOL(__blk_run_queue);
 
@@ -1070,6 +1083,50 @@
 }
 EXPORT_SYMBOL(blk_requeue_request);
 
+/**
+ * blk_reinsert_request() - Insert a request back to the scheduler
+ * @q:		request queue
+ * @rq:		request to be inserted
+ *
+ * This function inserts the request back to the scheduler as if
+ * it was never dispatched.
+ *
+ * Return: 0 on success, error code on fail
+ */
+int blk_reinsert_request(struct request_queue *q, struct request *rq)
+{
+	if (unlikely(!rq) || unlikely(!q))
+		return -EIO;
+
+	blk_delete_timer(rq);
+	blk_clear_rq_complete(rq);
+	trace_block_rq_requeue(q, rq);
+
+	if (blk_rq_tagged(rq))
+		blk_queue_end_tag(q, rq);
+
+	BUG_ON(blk_queued_rq(rq));
+
+	return elv_reinsert_request(q, rq);
+}
+EXPORT_SYMBOL(blk_reinsert_request);
+
+/**
+ * blk_reinsert_req_sup() - check whether the scheduler supports
+ *          reinsertion of requests
+ * @q:		request queue
+ *
+ * Returns true if the current scheduler supports reinserting
+ * request. False otherwise
+ */
+bool blk_reinsert_req_sup(struct request_queue *q)
+{
+	if (unlikely(!q))
+		return false;
+	return q->elevator->type->ops.elevator_reinsert_req_fn ? true : false;
+}
+EXPORT_SYMBOL(blk_reinsert_req_sup);
+
 static void add_acct_request(struct request_queue *q, struct request *rq,
 			     int where)
 {
@@ -2073,8 +2130,17 @@
 	struct request *rq;
 
 	rq = blk_peek_request(q);
-	if (rq)
+	if (rq) {
+		/*
+		 * Assumption: the next request fetched from scheduler after we
+		 * notified "urgent request pending" - will be the urgent one
+		 */
+		if (q->notified_urgent && !q->dispatched_urgent) {
+			q->dispatched_urgent = true;
+			(void)blk_mark_rq_urgent(rq);
+		}
 		blk_start_request(rq);
+	}
 	return rq;
 }
 EXPORT_SYMBOL(blk_fetch_request);
diff --git a/block/blk-settings.c b/block/blk-settings.c
index d3234fc..579328c 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -100,6 +100,18 @@
 EXPORT_SYMBOL_GPL(blk_queue_lld_busy);
 
 /**
+ * blk_urgent_request() - Set an urgent_request handler function for queue
+ * @q:		queue
+ * @fn:		handler for urgent requests
+ *
+ */
+void blk_urgent_request(struct request_queue *q, request_fn_proc *fn)
+{
+	q->urgent_request_fn = fn;
+}
+EXPORT_SYMBOL(blk_urgent_request);
+
+/**
  * blk_set_default_limits - reset limits to default values
  * @lim:  the queue_limits structure to reset
  *
diff --git a/block/blk.h b/block/blk.h
index d45be87..a52209f 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -39,6 +39,7 @@
  */
 enum rq_atomic_flags {
 	REQ_ATOM_COMPLETE = 0,
+	REQ_ATOM_URGENT = 1,
 };
 
 /*
@@ -55,6 +56,16 @@
 	clear_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags);
 }
 
+static inline int blk_mark_rq_urgent(struct request *rq)
+{
+	return test_and_set_bit(REQ_ATOM_URGENT, &rq->atomic_flags);
+}
+
+static inline void blk_clear_rq_urgent(struct request *rq)
+{
+	clear_bit(REQ_ATOM_URGENT, &rq->atomic_flags);
+}
+
 /*
  * Internal elevator interface
  */
diff --git a/block/elevator.c b/block/elevator.c
index 74fd51b..efec457 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -585,6 +585,41 @@
 	__elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE);
 }
 
+/**
+ * elv_reinsert_request() - Insert a request back to the scheduler
+ * @q:		request queue where request should be inserted
+ * @rq:		request to be inserted
+ *
+ * This function returns the request back to the scheduler to be
+ * inserted as if it was never dispatched
+ *
+ * Return: 0 on success, error code on failure
+ */
+int elv_reinsert_request(struct request_queue *q, struct request *rq)
+{
+	int res;
+
+	if (!q->elevator->type->ops.elevator_reinsert_req_fn)
+		return -EPERM;
+
+	res = q->elevator->type->ops.elevator_reinsert_req_fn(q, rq);
+	if (!res) {
+		/*
+		 * it already went through dequeue, we need to decrement the
+		 * in_flight count again
+		 */
+		if (blk_account_rq(rq)) {
+			q->in_flight[rq_is_sync(rq)]--;
+			if (rq->cmd_flags & REQ_SORTED)
+				elv_deactivate_rq(q, rq);
+		}
+		rq->cmd_flags &= ~REQ_STARTED;
+		q->nr_sorted++;
+	}
+
+	return res;
+}
+
 void elv_drain_elevator(struct request_queue *q)
 {
 	static int printed;
@@ -779,6 +814,11 @@
 {
 	struct elevator_queue *e = q->elevator;
 
+	if (test_bit(REQ_ATOM_URGENT, &rq->atomic_flags)) {
+		q->notified_urgent = false;
+		q->dispatched_urgent = false;
+		blk_clear_rq_urgent(rq);
+	}
 	/*
 	 * request is released from the driver, io must be done
 	 */
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index c1cbfea..55597fc 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -598,7 +598,7 @@
 	/* 8x25 returns 0 for minor id, but it should be 1 */
 	if (cpu_is_qsd8x50())
 		patchid = 1;
-	else if (cpu_is_msm8625() && minorid == 0)
+	else if ((cpu_is_msm8625() || cpu_is_msm8625q()) && minorid == 0)
 		minorid = 1;
 
 	chipid |= (minorid << 8) | patchid;
diff --git a/drivers/hwmon/epm_adc.c b/drivers/hwmon/epm_adc.c
index 69a2f1c..606bc36 100644
--- a/drivers/hwmon/epm_adc.c
+++ b/drivers/hwmon/epm_adc.c
@@ -1324,6 +1324,10 @@
 				return -EINVAL;
 			}
 
+			psoc_get_data.reading_value = epm_psoc_scale_result(
+				psoc_get_data.reading_value,
+				psoc_get_data.chan_num);
+
 			if (copy_to_user((void __user *)arg, &psoc_get_data,
 				sizeof(struct epm_psoc_get_data)))
 				return -EFAULT;
@@ -1529,38 +1533,38 @@
 }
 
 static struct sensor_device_attribute epm_adc_psoc_in_attrs[] = {
-	SENSOR_ATTR(ads0_chan0,  S_IRUGO, epm_adc_psoc_show_in, NULL, 0),
-	SENSOR_ATTR(ads0_chan1,  S_IRUGO, epm_adc_psoc_show_in, NULL, 1),
-	SENSOR_ATTR(ads0_chan2,  S_IRUGO, epm_adc_psoc_show_in, NULL, 2),
-	SENSOR_ATTR(ads0_chan3,  S_IRUGO, epm_adc_psoc_show_in, NULL, 3),
-	SENSOR_ATTR(ads0_chan4,  S_IRUGO, epm_adc_psoc_show_in, NULL, 4),
-	SENSOR_ATTR(ads0_chan5,  S_IRUGO, epm_adc_psoc_show_in, NULL, 5),
-	SENSOR_ATTR(ads0_chan6,  S_IRUGO, epm_adc_psoc_show_in, NULL, 6),
-	SENSOR_ATTR(ads0_chan7,  S_IRUGO, epm_adc_psoc_show_in, NULL, 7),
-	SENSOR_ATTR(ads0_chan8,  S_IRUGO, epm_adc_psoc_show_in, NULL, 8),
-	SENSOR_ATTR(ads0_chan9,  S_IRUGO, epm_adc_psoc_show_in, NULL, 9),
-	SENSOR_ATTR(ads0_chan10, S_IRUGO, epm_adc_psoc_show_in, NULL, 10),
-	SENSOR_ATTR(ads0_chan11, S_IRUGO, epm_adc_psoc_show_in, NULL, 11),
-	SENSOR_ATTR(ads0_chan12, S_IRUGO, epm_adc_psoc_show_in, NULL, 12),
-	SENSOR_ATTR(ads0_chan13, S_IRUGO, epm_adc_psoc_show_in, NULL, 13),
-	SENSOR_ATTR(ads0_chan14, S_IRUGO, epm_adc_psoc_show_in, NULL, 14),
-	SENSOR_ATTR(ads0_chan15, S_IRUGO, epm_adc_psoc_show_in, NULL, 15),
-	SENSOR_ATTR(ads1_chan0,  S_IRUGO, epm_adc_psoc_show_in, NULL, 16),
-	SENSOR_ATTR(ads1_chan1,  S_IRUGO, epm_adc_psoc_show_in, NULL, 17),
-	SENSOR_ATTR(ads1_chan2,  S_IRUGO, epm_adc_psoc_show_in, NULL, 18),
-	SENSOR_ATTR(ads1_chan3,  S_IRUGO, epm_adc_psoc_show_in, NULL, 19),
-	SENSOR_ATTR(ads1_chan4,  S_IRUGO, epm_adc_psoc_show_in, NULL, 20),
-	SENSOR_ATTR(ads1_chan5,  S_IRUGO, epm_adc_psoc_show_in, NULL, 21),
-	SENSOR_ATTR(ads1_chan6,  S_IRUGO, epm_adc_psoc_show_in, NULL, 22),
-	SENSOR_ATTR(ads1_chan7,  S_IRUGO, epm_adc_psoc_show_in, NULL, 23),
-	SENSOR_ATTR(ads1_chan8,  S_IRUGO, epm_adc_psoc_show_in, NULL, 24),
-	SENSOR_ATTR(ads1_chan9,  S_IRUGO, epm_adc_psoc_show_in, NULL, 25),
-	SENSOR_ATTR(ads1_chan10, S_IRUGO, epm_adc_psoc_show_in, NULL, 26),
-	SENSOR_ATTR(ads1_chan11, S_IRUGO, epm_adc_psoc_show_in, NULL, 27),
-	SENSOR_ATTR(ads1_chan12, S_IRUGO, epm_adc_psoc_show_in, NULL, 28),
-	SENSOR_ATTR(ads1_chan13, S_IRUGO, epm_adc_psoc_show_in, NULL, 29),
-	SENSOR_ATTR(ads1_chan14, S_IRUGO, epm_adc_psoc_show_in, NULL, 30),
-	SENSOR_ATTR(ads1_chan15, S_IRUGO, epm_adc_psoc_show_in, NULL, 31),
+	SENSOR_ATTR(psoc0_chan0,  S_IRUGO, epm_adc_psoc_show_in, NULL, 0),
+	SENSOR_ATTR(psoc0_chan1,  S_IRUGO, epm_adc_psoc_show_in, NULL, 1),
+	SENSOR_ATTR(psoc0_chan2,  S_IRUGO, epm_adc_psoc_show_in, NULL, 2),
+	SENSOR_ATTR(psoc0_chan3,  S_IRUGO, epm_adc_psoc_show_in, NULL, 3),
+	SENSOR_ATTR(psoc0_chan4,  S_IRUGO, epm_adc_psoc_show_in, NULL, 4),
+	SENSOR_ATTR(psoc0_chan5,  S_IRUGO, epm_adc_psoc_show_in, NULL, 5),
+	SENSOR_ATTR(psoc0_chan6,  S_IRUGO, epm_adc_psoc_show_in, NULL, 6),
+	SENSOR_ATTR(psoc0_chan7,  S_IRUGO, epm_adc_psoc_show_in, NULL, 7),
+	SENSOR_ATTR(psoc0_chan8,  S_IRUGO, epm_adc_psoc_show_in, NULL, 8),
+	SENSOR_ATTR(psoc0_chan9,  S_IRUGO, epm_adc_psoc_show_in, NULL, 9),
+	SENSOR_ATTR(psoc0_chan10, S_IRUGO, epm_adc_psoc_show_in, NULL, 10),
+	SENSOR_ATTR(psoc0_chan11, S_IRUGO, epm_adc_psoc_show_in, NULL, 11),
+	SENSOR_ATTR(psoc0_chan12, S_IRUGO, epm_adc_psoc_show_in, NULL, 12),
+	SENSOR_ATTR(psoc0_chan13, S_IRUGO, epm_adc_psoc_show_in, NULL, 13),
+	SENSOR_ATTR(psoc0_chan14, S_IRUGO, epm_adc_psoc_show_in, NULL, 14),
+	SENSOR_ATTR(psoc0_chan15, S_IRUGO, epm_adc_psoc_show_in, NULL, 15),
+	SENSOR_ATTR(psoc0_chan16,  S_IRUGO, epm_adc_psoc_show_in, NULL, 16),
+	SENSOR_ATTR(psoc0_chan17,  S_IRUGO, epm_adc_psoc_show_in, NULL, 17),
+	SENSOR_ATTR(psoc0_chan18,  S_IRUGO, epm_adc_psoc_show_in, NULL, 18),
+	SENSOR_ATTR(psoc0_chan19,  S_IRUGO, epm_adc_psoc_show_in, NULL, 19),
+	SENSOR_ATTR(psoc0_chan20,  S_IRUGO, epm_adc_psoc_show_in, NULL, 20),
+	SENSOR_ATTR(psoc0_chan21,  S_IRUGO, epm_adc_psoc_show_in, NULL, 21),
+	SENSOR_ATTR(psoc0_chan22,  S_IRUGO, epm_adc_psoc_show_in, NULL, 22),
+	SENSOR_ATTR(psoc0_chan23,  S_IRUGO, epm_adc_psoc_show_in, NULL, 23),
+	SENSOR_ATTR(psoc0_chan24,  S_IRUGO, epm_adc_psoc_show_in, NULL, 24),
+	SENSOR_ATTR(psoc0_chan25,  S_IRUGO, epm_adc_psoc_show_in, NULL, 25),
+	SENSOR_ATTR(psoc0_chan26, S_IRUGO, epm_adc_psoc_show_in, NULL, 26),
+	SENSOR_ATTR(psoc0_chan27, S_IRUGO, epm_adc_psoc_show_in, NULL, 27),
+	SENSOR_ATTR(psoc0_chan28, S_IRUGO, epm_adc_psoc_show_in, NULL, 28),
+	SENSOR_ATTR(psoc0_chan29, S_IRUGO, epm_adc_psoc_show_in, NULL, 29),
+	SENSOR_ATTR(psoc0_chan30, S_IRUGO, epm_adc_psoc_show_in, NULL, 30),
+	SENSOR_ATTR(psoc0_chan31, S_IRUGO, epm_adc_psoc_show_in, NULL, 31),
 };
 
 static int __devinit epm_adc_psoc_init_hwmon(struct spi_device *spi,
@@ -1677,6 +1681,15 @@
 	epm_adc = epm_adc_drv;
 	epm_adc->misc.name = EPM_ADC_DRIVER_NAME;
 	epm_adc->misc.minor = MISC_DYNAMIC_MINOR;
+
+	if (node) {
+		epm_adc->misc.fops = &epm_adc_fops;
+		if (misc_register(&epm_adc->misc)) {
+			pr_err("Unable to register misc device!\n");
+			return -EFAULT;
+		}
+	}
+
 	epm_adc_drv->epm_spi_client = spi;
 	epm_adc_drv->epm_spi_client->bits_per_word =
 				EPM_ADC_ADS_SPI_BITS_PER_WORD;
diff --git a/drivers/input/touchscreen/cyttsp-i2c-qc.c b/drivers/input/touchscreen/cyttsp-i2c-qc.c
index f96348e..6eba5d1 100644
--- a/drivers/input/touchscreen/cyttsp-i2c-qc.c
+++ b/drivers/input/touchscreen/cyttsp-i2c-qc.c
@@ -2778,11 +2778,14 @@
 			return -EINVAL;
 		}
 
+		mutex_init(&ts->mutex);
 		i2c_set_clientdata(client, ts);
 
 		error = cyttsp_initialize(client, ts);
 		if (error) {
 			cyttsp_xdebug1("err cyttsp_initialize\n");
+			/* release mutex */
+			mutex_destroy(&ts->mutex);
 			/* deallocate memory */
 			kfree(ts);
 /*
@@ -2801,7 +2804,6 @@
 	}
 #endif /* CONFIG_HAS_EARLYSUSPEND */
 	device_init_wakeup(&client->dev, ts->platform_data->wakeup);
-	mutex_init(&ts->mutex);
 
 	cyttsp_info("Start Probe %s\n", \
 		(retval < CY_OK) ? "FAIL" : "PASS");
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index a641ce9..f493129 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -70,6 +70,7 @@
 #define WLED_CTL_DLY_BIT_SHFT		0x05
 #define WLED_MAX_CURR			25
 #define WLED_MAX_CURR_MASK		0x1F
+#define WLED_BRIGHTNESS_MSB_MASK	0x0F
 #define WLED_OP_FDBCK_MASK		0x1C
 #define WLED_OP_FDBCK_BIT_SHFT		0x02
 
@@ -283,7 +284,8 @@
 			return rc;
 		}
 
-		val = (val & ~WLED_MAX_CURR_MASK) | (duty >> WLED_8_BIT_SHFT);
+		val = (val & ~WLED_BRIGHTNESS_MSB_MASK) |
+			(duty >> WLED_8_BIT_SHFT);
 		rc = pm8xxx_writeb(led->dev->parent,
 				WLED_BRIGHTNESS_CNTL_REG1(i), val);
 		if (rc) {
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index d2ed996..f33122f 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -35,6 +35,17 @@
 	   To compile this driver as a module, choose M here: the module will
 	   be called user-rc-input.
 
+config USER_SP_RC_INPUT
+	tristate "User Space Input device wrapper for Standby Processor Remote Control"
+	depends on RC_CORE
+
+	---help---
+	   Say Y if you want to report remote control input events
+	   from userspace.
+
+	   To compile this driver as a module, choose M here: the module will
+	   be called user-sp-input.
+
 source "drivers/media/rc/keymaps/Kconfig"
 
 config IR_NEC_DECODER
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index be02eec..fdc3e99 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -14,6 +14,7 @@
 obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
 obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
 obj-$(CONFIG_USER_RC_INPUT) += user-rc-input.o
+obj-$(CONFIG_USER_SP_RC_INPUT) += user-sp-rc-input.o
 
 # stand-alone IR receivers/transmitters
 obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o
diff --git a/drivers/media/rc/user-sp-rc-input.c b/drivers/media/rc/user-sp-rc-input.c
new file mode 100644
index 0000000..83da95d
--- /dev/null
+++ b/drivers/media/rc/user-sp-rc-input.c
@@ -0,0 +1,246 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/slab.h>
+
+#include <media/rc-core.h>
+#include <media/user-rc-input.h>
+
+#define MAX_SP_DEVICES		1
+#define USER_SP_INPUT_DEV_NAME	"user-sp-input"
+#define USER_SP_INPUT_DRV_NAME	"sp-user-input"
+
+struct user_sp_input_dev {
+	struct cdev sp_input_cdev;
+	struct class *sp_input_class;
+	struct device *sp_input_dev;
+	struct rc_dev *spdev;
+	dev_t sp_input_base_dev;
+	struct device *dev;
+	int in_use;
+};
+
+static int user_sp_input_open(struct inode *inode, struct file *file)
+{
+	struct cdev *input_cdev = inode->i_cdev;
+	struct user_sp_input_dev *input_dev =
+	container_of(input_cdev, struct user_sp_input_dev, sp_input_cdev);
+
+	if (input_dev->in_use) {
+		dev_err(input_dev->dev,
+		"Device is already open..only one instance is allowed\n");
+		return -EBUSY;
+	}
+	input_dev->in_use++;
+	file->private_data = input_dev;
+
+	return 0;
+}
+
+static int user_sp_input_release(struct inode *inode, struct file *file)
+{
+	struct user_sp_input_dev *input_dev = file->private_data;
+
+	input_dev->in_use--;
+
+	return 0;
+}
+
+static ssize_t user_sp_input_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *ppos)
+{
+	int ret = count;
+	struct user_sp_input_dev *input_dev = file->private_data;
+	unsigned char cmd = 0;
+	int scancode = 0;
+
+	if (copy_from_user(&cmd, buffer, 1)) {
+		dev_err(input_dev->dev, "Copy from user failed\n");
+		ret = -EFAULT;
+		goto out_free;
+	}
+
+	if (copy_from_user(&scancode, &buffer[1], 4)) {
+		dev_err(input_dev->dev, "Copy from user failed\n");
+		ret = -EFAULT;
+		goto out_free;
+	}
+
+	switch (cmd) {
+	case USER_CONTROL_PRESSED:
+		dev_dbg(input_dev->dev, "user controlled pressed 0x%x\n",
+			scancode);
+		rc_keydown(input_dev->spdev, scancode, 0);
+		break;
+	case USER_CONTROL_REPEATED:
+		dev_dbg(input_dev->dev, "user controlled repeated 0x%x\n",
+			scancode);
+		rc_repeat(input_dev->spdev);
+		break;
+	case USER_CONTROL_RELEASED:
+		dev_dbg(input_dev->dev, "user controlled released 0x%x\n",
+			scancode);
+		rc_keyup(input_dev->spdev);
+		break;
+	}
+
+out_free:
+	return ret;
+}
+
+const struct file_operations sp_fops = {
+	.owner  = THIS_MODULE,
+	.open   = user_sp_input_open,
+	.write  = user_sp_input_write,
+	.release = user_sp_input_release,
+};
+
+static int __devinit user_sp_input_probe(struct platform_device *pdev)
+{
+	struct user_sp_input_dev *user_sp_dev;
+	struct rc_dev *spdev;
+	int retval;
+
+	user_sp_dev = kzalloc(sizeof(struct user_sp_input_dev), GFP_KERNEL);
+	if (!user_sp_dev)
+		return -ENOMEM;
+
+	user_sp_dev->sp_input_class = class_create(THIS_MODULE,
+						"user-sp-input-loopback");
+
+	if (IS_ERR(user_sp_dev->sp_input_class)) {
+		retval = PTR_ERR(user_sp_dev->sp_input_class);
+		goto err;
+	}
+
+	retval = alloc_chrdev_region(&user_sp_dev->sp_input_base_dev, 0,
+				MAX_SP_DEVICES, USER_SP_INPUT_DEV_NAME);
+
+	if (retval) {
+		dev_err(&pdev->dev,
+			"alloc_chrdev_region failed\n");
+		goto alloc_chrdev_err;
+	}
+
+	dev_info(&pdev->dev, "User space report standby key event input" \
+				" driver registered, major %d\n",
+				MAJOR(user_sp_dev->sp_input_base_dev));
+
+	cdev_init(&user_sp_dev->sp_input_cdev, &sp_fops);
+	retval = cdev_add(&user_sp_dev->sp_input_cdev,
+			user_sp_dev->sp_input_base_dev, MAX_SP_DEVICES);
+	if (retval) {
+		dev_err(&pdev->dev, "cdev_add failed\n");
+		goto cdev_add_err;
+	}
+	user_sp_dev->sp_input_dev = device_create(user_sp_dev->sp_input_class,
+		NULL, MKDEV(MAJOR(user_sp_dev->sp_input_base_dev), 0), NULL,
+		"user-sp-input-dev%d", 0);
+
+	if (IS_ERR(user_sp_dev->sp_input_dev)) {
+		retval = PTR_ERR(user_sp_dev->sp_input_dev);
+		dev_err(&pdev->dev, "device_create failed\n");
+		goto device_create_err;
+	}
+
+	spdev = rc_allocate_device();
+	if (!spdev) {
+		dev_err(&pdev->dev, "failed to allocate rc device");
+		retval = -ENOMEM;
+		goto err_allocate_device;
+	}
+
+	spdev->driver_type = RC_DRIVER_SCANCODE;
+	spdev->allowed_protos = RC_TYPE_OTHER;
+	spdev->input_name = USER_SP_INPUT_DEV_NAME;
+	spdev->input_id.bustype = BUS_HOST;
+	spdev->driver_name = USER_SP_INPUT_DRV_NAME;
+	spdev->map_name = RC_MAP_RC6_PHILIPS;
+
+	retval = rc_register_device(spdev);
+	if (retval < 0) {
+		dev_err(&pdev->dev, "failed to register rc device\n");
+		goto rc_register_err;
+	}
+	user_sp_dev->spdev = spdev;
+	user_sp_dev->dev = &pdev->dev;
+	platform_set_drvdata(pdev, user_sp_dev);
+	user_sp_dev->in_use = 0;
+
+	return 0;
+
+rc_register_err:
+	rc_free_device(spdev);
+err_allocate_device:
+	device_destroy(user_sp_dev->sp_input_class,
+			MKDEV(MAJOR(user_sp_dev->sp_input_base_dev), 0));
+cdev_add_err:
+	unregister_chrdev_region(user_sp_dev->sp_input_base_dev,
+				MAX_SP_DEVICES);
+device_create_err:
+	cdev_del(&user_sp_dev->sp_input_cdev);
+alloc_chrdev_err:
+	class_destroy(user_sp_dev->sp_input_class);
+err:
+	kfree(user_sp_dev);
+	return retval;
+}
+
+static int __devexit user_sp_input_remove(struct platform_device *pdev)
+{
+	struct user_sp_input_dev *user_sp_dev = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	rc_free_device(user_sp_dev->spdev);
+	device_destroy(user_sp_dev->sp_input_class,
+			MKDEV(MAJOR(user_sp_dev->sp_input_base_dev), 0));
+	unregister_chrdev_region(user_sp_dev->sp_input_base_dev,
+				MAX_SP_DEVICES);
+	cdev_del(&user_sp_dev->sp_input_cdev);
+	class_destroy(user_sp_dev->sp_input_class);
+	kfree(user_sp_dev);
+
+	return 0;
+}
+
+static struct platform_driver user_sp_input_driver = {
+	.probe  = user_sp_input_probe,
+	.remove = __devexit_p(user_sp_input_remove),
+	.driver = {
+		.name   = USER_SP_INPUT_DRV_NAME,
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init user_sp_input_init(void)
+{
+	return platform_driver_register(&user_sp_input_driver);
+}
+module_init(user_sp_input_init);
+
+static void __exit user_sp_input_exit(void)
+{
+	platform_driver_unregister(&user_sp_input_driver);
+}
+module_exit(user_sp_input_exit);
+
+MODULE_DESCRIPTION("User SP RC Input driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index d797ba7..fa056ca 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -729,7 +729,7 @@
 	mutex_unlock(&bufq->lock);
 	if (!found) {
 		dprintk(VIDC_ERR,
-			"Failed to find the buffer in queued list: %d, %d\n",
+			"Failed to find the buffer in queued list: 0x%x, %d\n",
 			dev_addr, q->type);
 		vb = NULL;
 	}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 76e9b9c..0b5449e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -136,6 +136,10 @@
 module_param(perdev_minors, int, 0444);
 MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
 
+static inline int mmc_blk_part_switch(struct mmc_card *card,
+				      struct mmc_blk_data *md);
+static int get_card_status(struct mmc_card *card, u32 *status, int retries);
+
 static inline void mmc_blk_clear_packed(struct mmc_queue_req *mqrq)
 {
 	mqrq->packed_cmd = MMC_PACKED_NONE;
@@ -463,6 +467,38 @@
 	return ERR_PTR(err);
 }
 
+static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status,
+				       u32 retries_max)
+{
+	int err;
+	u32 retry_count = 0;
+
+	if (!status || !retries_max)
+		return -EINVAL;
+
+	do {
+		err = get_card_status(card, status, 5);
+		if (err)
+			break;
+
+		if (!R1_STATUS(*status) &&
+				(R1_CURRENT_STATE(*status) != R1_STATE_PRG))
+			break; /* RPMB programming operation complete */
+
+		/*
+		 * Rechedule to give the MMC device a chance to continue
+		 * processing the previous command without being polled too
+		 * frequently.
+		 */
+		usleep_range(1000, 5000);
+	} while (++retry_count < retries_max);
+
+	if (retry_count == retries_max)
+		err = -EPERM;
+
+	return err;
+}
+
 static int mmc_blk_ioctl_cmd(struct block_device *bdev,
 	struct mmc_ioc_cmd __user *ic_ptr)
 {
@@ -474,6 +510,8 @@
 	struct mmc_request mrq = {NULL};
 	struct scatterlist sg;
 	int err;
+	int is_rpmb = false;
+	u32 status = 0;
 
 	/*
 	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
@@ -493,6 +531,9 @@
 		goto cmd_done;
 	}
 
+	if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
+		is_rpmb = true;
+
 	card = md->queue.card;
 	if (IS_ERR(card)) {
 		err = PTR_ERR(card);
@@ -543,12 +584,23 @@
 
 	mmc_claim_host(card->host);
 
+	err = mmc_blk_part_switch(card, md);
+	if (err)
+		goto cmd_rel_host;
+
 	if (idata->ic.is_acmd) {
 		err = mmc_app_cmd(card->host, card);
 		if (err)
 			goto cmd_rel_host;
 	}
 
+	if (is_rpmb) {
+		err = mmc_set_blockcount(card, data.blocks,
+			idata->ic.write_flag & (1 << 31));
+		if (err)
+			goto cmd_rel_host;
+	}
+
 	mmc_wait_for_req(card->host, &mrq);
 
 	if (cmd.error) {
@@ -584,6 +636,18 @@
 		}
 	}
 
+	if (is_rpmb) {
+		/*
+		 * Ensure RPMB command has completed by polling CMD13
+		 * "Send Status".
+		 */
+		err = ioctl_rpmb_card_status_poll(card, &status, 5);
+		if (err)
+			dev_err(mmc_dev(card->host),
+					"%s: Card Status=0x%08X, error %d\n",
+					__func__, status, err);
+	}
+
 cmd_rel_host:
 	mmc_release_host(card->host);
 
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index f91ba89..89f834a 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2214,6 +2214,20 @@
 }
 EXPORT_SYMBOL(mmc_set_blocklen);
 
+int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
+			bool is_rel_write)
+{
+	struct mmc_command cmd = {0};
+
+	cmd.opcode = MMC_SET_BLOCK_COUNT;
+	cmd.arg = blockcount & 0x0000FFFF;
+	if (is_rel_write)
+		cmd.arg |= 1 << 31;
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+	return mmc_wait_for_cmd(card->host, &cmd, 5);
+}
+EXPORT_SYMBOL(mmc_set_blockcount);
+
 static void mmc_hw_reset_for_init(struct mmc_host *host)
 {
 	if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset)
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index c8b47b9..00dc5bf 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -6536,19 +6536,19 @@
 
 #if CONFIG_DEBUG_FS
 static void msmsdcc_print_pm_stats(struct msmsdcc_host *host, ktime_t start,
-		const char *func)
+				   const char *func, int err)
 {
 	ktime_t diff;
 
-	if (host->print_pm_stats) {
+	if (host->print_pm_stats && !err) {
 		diff = ktime_sub(ktime_get(), start);
-		pr_info("%s: %s: Completed in %llu usec\n", func,
-		mmc_hostname(host->mmc), (u64)ktime_to_us(diff));
+		pr_info("%s: %s: Completed in %llu usec\n",
+			mmc_hostname(host->mmc), func, (u64)ktime_to_us(diff));
 	}
 }
 #else
 static void msmsdcc_print_pm_stats(struct msmsdcc_host *host, ktime_t start,
-		const char *func) {}
+				   const char *func, int err) {}
 #endif
 
 static int
@@ -6615,7 +6615,7 @@
 out:
 	/* set bus bandwidth to 0 immediately */
 	msmsdcc_msm_bus_cancel_work_and_set_vote(host, NULL);
-	msmsdcc_print_pm_stats(host, start, __func__);
+	msmsdcc_print_pm_stats(host, start, __func__, rc);
 	return rc;
 }
 
@@ -6664,7 +6664,7 @@
 	host->pending_resume = false;
 	pr_debug("%s: %s: end\n", mmc_hostname(mmc), __func__);
 out:
-	msmsdcc_print_pm_stats(host, start, __func__);
+	msmsdcc_print_pm_stats(host, start, __func__, 0);
 	return 0;
 }
 
@@ -6701,7 +6701,7 @@
 	if (!pm_runtime_suspended(dev))
 		rc = msmsdcc_runtime_suspend(dev);
  out:
-	msmsdcc_print_pm_stats(host, start, __func__);
+	msmsdcc_print_pm_stats(host, start, __func__, rc);
 	return rc;
 }
 
@@ -6757,7 +6757,7 @@
 		enable_irq(host->plat->status_irq);
 	}
 out:
-	msmsdcc_print_pm_stats(host, start, __func__);
+	msmsdcc_print_pm_stats(host, start, __func__, rc);
 	return rc;
 }
 
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index a3bbb73..af421ac 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -1167,6 +1167,7 @@
 	struct sps_iovec *desc;
 	struct sps_iovec iovec;
 	u32 next_write;
+	static int show_recom;
 
 	/* Is this a BAM-to-BAM or satellite connection? */
 	if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) {
@@ -1199,12 +1200,24 @@
 		if (!pipe->sys.ack_xfers && pipe->polled) {
 			pipe_handler_eot(dev, pipe);
 			if (next_write == pipe->sys.acked_offset) {
+				if (!show_recom) {
+					show_recom = true;
+					SPS_ERR("sps:Client of BAM 0x%x pipe %d is recommended to have flow control",
+						BAM_ID(dev), pipe_index);
+				}
+
 				SPS_DBG2("sps:Descriptor FIFO is full for BAM "
 					"0x%x pipe %d after pipe_handler_eot",
 					BAM_ID(dev), pipe_index);
 				return SPS_ERROR;
 			}
 		} else {
+			if (!show_recom) {
+				show_recom = true;
+				SPS_ERR("sps:Client of BAM 0x%x pipe %d is recommended to have flow control.",
+					BAM_ID(dev), pipe_index);
+			}
+
 			SPS_DBG2("sps:Descriptor FIFO is full for "
 				"BAM 0x%x pipe %d", BAM_ID(dev), pipe_index);
 			return SPS_ERROR;
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 12b186d..0a072b1 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -33,7 +33,7 @@
 #define BMS1_MODE_CTL			0X40
 /* Coulomb counter clear registers */
 #define BMS1_CC_DATA_CTL		0x42
-#define BMS1_CC_CLEAR_CTRL		0x43
+#define BMS1_CC_CLEAR_CTL		0x43
 /* OCV limit registers */
 #define BMS1_OCV_USE_LOW_LIMIT_THR0	0x48
 #define BMS1_OCV_USE_LOW_LIMIT_THR1	0x49
@@ -484,12 +484,49 @@
 	pr_debug("last_good_ocv_uv = %d\n", raw->last_good_ocv_uv);
 }
 
+#define CLEAR_CC			BIT(7)
+#define CLEAR_SW_CC			BIT(6)
+/**
+ * reset both cc and sw-cc.
+ * note: this should only be ever called from one thread
+ * or there may be a race condition where CC is never enabled
+ * again
+ */
+static void reset_cc(struct qpnp_bms_chip *chip)
+{
+	int rc;
+
+	pr_debug("resetting cc manually\n");
+	rc = qpnp_masked_write(chip, BMS1_CC_CLEAR_CTL,
+				CLEAR_CC | CLEAR_SW_CC,
+				CLEAR_CC | CLEAR_SW_CC);
+	if (rc)
+		pr_err("cc reset failed: %d\n", rc);
+
+	/* wait for 100us for cc to reset */
+	udelay(100);
+
+	rc = qpnp_masked_write(chip, BMS1_CC_CLEAR_CTL,
+				CLEAR_CC | CLEAR_SW_CC, 0);
+	if (rc)
+		pr_err("cc reenable failed: %d\n", rc);
+}
+
 static int read_soc_params_raw(struct qpnp_bms_chip *chip,
 				struct raw_soc_params *raw)
 {
 	int rc;
 
 	mutex_lock(&chip->bms_output_lock);
+
+	if (chip->prev_last_good_ocv_raw == 0) {
+		/* software workaround for BMS 1.0
+		 * The coulomb counter does not reset upon PON, so reset it
+		 * manually upon probe. */
+		if (chip->revision1 == 0 && chip->revision2 == 0)
+			reset_cc(chip);
+	}
+
 	lock_output_data(chip);
 
 	rc = qpnp_read_wrapper(chip, (u8 *)&raw->last_good_ocv_raw,
@@ -1980,6 +2017,7 @@
 		pr_err("Error reading version register %d\n", rc);
 		goto error_read;
 	}
+	pr_debug("BMS version: %hhu.%hhu\n", chip->revision2, chip->revision1);
 
 	rc = qpnp_vadc_is_ready();
 	if (rc) {
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 3de990c..0189a07 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -692,9 +692,9 @@
 	 * Configure Rx Watermark as 3/4 size of Rx FIFO.
 	 * RFWR register takes value in Words for UARTDM Core
 	 * whereas it is consider to be in Bytes for UART Core.
-	 * Hence configuring Rx Watermark as 12 Words.
+	 * Hence configuring Rx Watermark as 48 Words.
 	 */
-	watermark = (port->fifosize * 3) / (4*4);
+	watermark = (port->fifosize * 3) / 4;
 	msm_hsl_write(port, watermark, regmap[vid][UARTDM_RFWR]);
 
 	/* set TX watermark */
@@ -775,18 +775,15 @@
 #endif
 	pm_runtime_get_sync(port->dev);
 
-	/* Set RFR Level as 3/4 of UARTDM FIFO Size */
+	/*
+	 * Set RFR Level as 3/4 of UARTDM FIFO Size
+	 * i.e. 48 Words = 192 bytes as Rx FIFO is 64 words ( 256 bytes).
+	 */
 	if (likely(port->fifosize > 48))
 		rfr_level = port->fifosize - 16;
 	else
 		rfr_level = port->fifosize;
 
-	/*
-	 * Use rfr_level value in Words to program
-	 * MR1 register for UARTDM Core.
-	 */
-	rfr_level = (rfr_level / 4);
-
 	spin_lock_irqsave(&port->lock, flags);
 
 	vid = msm_hsl_port->ver_id;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index d416904..2b0a79f 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1248,6 +1248,10 @@
 		/* fall through */
 	case USB_CHG_STATE_DETECTED:
 		dwc3_chg_block_reset(mdwc);
+		/* Enable VDP_SRC */
+		if (mdwc->charger.chg_type == DWC3_DCP_CHARGER)
+			dwc3_msm_write_readback(mdwc->base,
+					CHARGING_DET_CTRL_REG, 0x1F, 0x10);
 		dev_dbg(mdwc->dev, "chg_type = %s\n",
 			chg_to_string(mdwc->charger.chg_type));
 		mdwc->charger.notify_detection_complete(mdwc->otg_xceiv->otg,
@@ -1279,6 +1283,7 @@
 static int dwc3_msm_suspend(struct dwc3_msm *mdwc)
 {
 	int ret;
+	bool dcp;
 
 	dev_dbg(mdwc->dev, "%s: entering lpm\n", __func__);
 
@@ -1287,23 +1292,29 @@
 		return 0;
 	}
 
+	if (mdwc->hs_phy_irq)
+		disable_irq(mdwc->hs_phy_irq);
+
 	if (cancel_delayed_work_sync(&mdwc->chg_work))
 		dev_dbg(mdwc->dev, "%s: chg_work was pending\n", __func__);
 	if (mdwc->chg_state != USB_CHG_STATE_DETECTED) {
 		/* charger detection wasn't complete; re-init flags */
 		mdwc->chg_state = USB_CHG_STATE_UNDEFINED;
 		mdwc->charger.chg_type = DWC3_INVALID_CHARGER;
+		dwc3_msm_write_readback(mdwc->base, CHARGING_DET_CTRL_REG,
+								0x37, 0x0);
 	}
 
+	dcp = mdwc->charger.chg_type == DWC3_DCP_CHARGER;
+
 	/* Sequence to put hardware in low power state:
 	 * 1. Set OTGDISABLE to disable OTG block in HSPHY (saves power)
-	 * 2. Clear charger detection control fields
+	 * 2. Clear charger detection control fields (performed above)
 	 * 3. SUSPEND PHY and turn OFF core clock after some delay
 	 * 4. Clear interrupt latch register and enable BSV, ID HV interrupts
 	 * 5. Enable PHY retention
 	 */
 	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x1000, 0x1000);
-	dwc3_msm_write_readback(mdwc->base, CHARGING_DET_CTRL_REG, 0x37, 0x0);
 	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
 						0xC00000, 0x800000);
 
@@ -1323,7 +1334,8 @@
 
 	dwc3_msm_write_reg(mdwc->base, HS_PHY_IRQ_STAT_REG, 0xFFF);
 	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x18000, 0x18000);
-	dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x2, 0x0);
+	if (!dcp)
+		dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0x2, 0x0);
 
 	/* make sure above writes are completed before turning off clocks */
 	wmb();
@@ -1343,7 +1355,7 @@
 			dev_err(mdwc->dev, "Failed to reset bus bw vote\n");
 	}
 
-	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability)
+	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability && !dcp)
 		dwc3_hsusb_ldo_enable(0);
 
 	dwc3_ssusb_ldo_enable(0);
@@ -1354,12 +1366,16 @@
 
 	dev_info(mdwc->dev, "DWC3 in low power mode\n");
 
+	if (mdwc->hs_phy_irq)
+		enable_irq(mdwc->hs_phy_irq);
+
 	return 0;
 }
 
 static int dwc3_msm_resume(struct dwc3_msm *mdwc)
 {
 	int ret;
+	bool dcp;
 
 	dev_dbg(mdwc->dev, "%s: exiting lpm\n", __func__);
 
@@ -1383,7 +1399,8 @@
 		dev_err(mdwc->dev, "%s failed to vote for TCXO buffer%d\n",
 						__func__, ret);
 
-	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability)
+	dcp = mdwc->charger.chg_type == DWC3_DCP_CHARGER;
+	if (mdwc->otg_xceiv && mdwc->ext_xceiv.otg_capability && !dcp)
 		dwc3_hsusb_ldo_enable(1);
 
 	dwc3_ssusb_ldo_enable(1);
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index 96bfb9f..ee4a578 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1249,7 +1249,6 @@
 	/* transmit read comamnd to client */
 	mipi_dsi_cmd_dma_tx(tp);
 
-	mipi_dsi_disable_irq(DSI_CMD_TERM);
 	/*
 	 * once cmd_dma_done interrupt received,
 	 * return data from client is ready and stored
@@ -1359,7 +1358,6 @@
 	/* transmit read comamnd to client */
 	mipi_dsi_cmd_dma_tx(tp);
 
-	mipi_dsi_disable_irq(DSI_CMD_TERM);
 	/*
 	 * once cmd_dma_done interrupt received,
 	 * return data from client is ready and stored
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e76b0ae..6502841 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -282,6 +282,7 @@
 	struct request_list	rq;
 
 	request_fn_proc		*request_fn;
+	request_fn_proc		*urgent_request_fn;
 	make_request_fn		*make_request_fn;
 	prep_rq_fn		*prep_rq_fn;
 	unprep_rq_fn		*unprep_rq_fn;
@@ -365,6 +366,8 @@
 	struct list_head	icq_list;
 
 	struct queue_limits	limits;
+	bool			notified_urgent;
+	bool			dispatched_urgent;
 
 	/*
 	 * sg stuff
@@ -673,6 +676,8 @@
 extern struct request *blk_make_request(struct request_queue *, struct bio *,
 					gfp_t);
 extern void blk_requeue_request(struct request_queue *, struct request *);
+extern int blk_reinsert_request(struct request_queue *q, struct request *rq);
+extern bool blk_reinsert_req_sup(struct request_queue *q);
 extern void blk_add_request_payload(struct request *rq, struct page *page,
 		unsigned int len);
 extern int blk_rq_check_limits(struct request_queue *q, struct request *rq);
@@ -822,6 +827,7 @@
 extern struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *);
 extern struct request_queue *blk_init_allocated_queue(struct request_queue *,
 						      request_fn_proc *, spinlock_t *);
+extern void blk_urgent_request(struct request_queue *q, request_fn_proc *fn);
 extern void blk_cleanup_queue(struct request_queue *);
 extern void blk_queue_make_request(struct request_queue *, make_request_fn *);
 extern void blk_queue_bounce_limit(struct request_queue *, u64);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 7d4e035..b36b28f 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -22,6 +22,9 @@
 typedef int (elevator_dispatch_fn) (struct request_queue *, int);
 
 typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
+typedef int (elevator_reinsert_req_fn) (struct request_queue *,
+					struct request *);
+typedef bool (elevator_is_urgent_fn) (struct request_queue *);
 typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *);
 typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
 typedef int (elevator_may_queue_fn) (struct request_queue *, int);
@@ -46,6 +49,9 @@
 
 	elevator_dispatch_fn *elevator_dispatch_fn;
 	elevator_add_req_fn *elevator_add_req_fn;
+	elevator_reinsert_req_fn *elevator_reinsert_req_fn;
+	elevator_is_urgent_fn *elevator_is_urgent_fn;
+
 	elevator_activate_req_fn *elevator_activate_req_fn;
 	elevator_deactivate_req_fn *elevator_deactivate_req_fn;
 
@@ -122,6 +128,7 @@
 extern void elv_bio_merged(struct request_queue *q, struct request *,
 				struct bio *);
 extern void elv_requeue_request(struct request_queue *, struct request *);
+extern int elv_reinsert_request(struct request_queue *, struct request *);
 extern struct request *elv_former_request(struct request_queue *, struct request *);
 extern struct request *elv_latter_request(struct request_queue *, struct request *);
 extern int elv_register_queue(struct request_queue *q);
diff --git a/include/linux/epm_adc.h b/include/linux/epm_adc.h
index ca1a425..14cb148 100644
--- a/include/linux/epm_adc.h
+++ b/include/linux/epm_adc.h
@@ -13,55 +13,54 @@
 	int32_t physical;
 };
 
-#ifdef __KERNEL__
 struct epm_psoc_init_resp {
-	u8	cmd;
-	u8	version;
-	u8	compatible_ver;
-	u8	firm_ver[3];
-	u8	num_dev;
-	u8	num_channel;
+	uint8_t	cmd;
+	uint8_t	version;
+	uint8_t	compatible_ver;
+	uint8_t	firm_ver[3];
+	uint8_t	num_dev;
+	uint8_t	num_channel;
 };
 
 struct epm_psoc_channel_configure {
-	u8		cmd;
-	u8		device_num;
+	uint8_t		cmd;
+	uint8_t		device_num;
 	uint32_t	channel_num;
 };
 
 struct epm_psoc_set_avg {
-	u8	cmd;
-	u8	avg_period;
-	u8	return_code;
+	uint8_t	cmd;
+	uint8_t	avg_period;
+	uint8_t	return_code;
 };
 
 struct epm_psoc_get_data {
-	u8		cmd;
-	u8		dev_num;
-	u8		chan_num;
+	uint8_t		cmd;
+	uint8_t		dev_num;
+	uint8_t		chan_num;
 	uint32_t	timestamp_resp_value;
 	uint32_t	reading_value;
 };
 
 struct epm_psoc_get_buffered_data {
-	u8		cmd;
-	u8		dev_num;
-	u8		status_mask;
-	u8		chan_idx;
+	uint8_t		cmd;
+	uint8_t		dev_num;
+	uint8_t		status_mask;
+	uint8_t		chan_idx;
 	uint32_t	chan_mask;
 	uint32_t	timestamp_start;
 	uint32_t	timestamp_end;
-	u8		buff_data[48];
+	uint8_t		buff_data[48];
 };
 
 struct epm_psoc_system_time_stamp {
-	u8		cmd;
+	uint8_t		cmd;
 	uint32_t	timestamp;
 };
 
 struct epm_psoc_set_channel {
-	u8		cmd;
-	u8		dev_num;
+	uint8_t		cmd;
+	uint8_t		dev_num;
 	uint32_t	channel_mask;
 };
 
@@ -72,23 +71,23 @@
 };
 
 struct epm_psoc_get_avg_buffered_switch_data {
-	u8			cmd;
-	u8			status;
+	uint8_t			cmd;
+	uint8_t			status;
 	uint32_t		timestamp_start;
 	uint32_t		channel_mask;
-	u8			avg_data[54];
+	uint8_t			avg_data[54];
 	struct result_buffer	data[54];
 };
 
 struct epm_psoc_set_channel_switch {
-	u8		cmd;
-	u8		dev;
+	uint8_t		cmd;
+	uint8_t		dev;
 	uint32_t	delay;
 };
 
 struct epm_psoc_set_vadc {
-	u8		cmd;
-	u8		vadc_dev;
+	uint8_t		cmd;
+	uint8_t		vadc_dev;
 	uint32_t	vadc_voltage;
 };
 
@@ -97,6 +96,7 @@
 	uint32_t gain;
 };
 
+#ifdef __KERNEL__
 struct epm_adc_platform_data {
 	struct epm_chan_properties *channel;
 	uint32_t num_channels;
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 7247696..24b9790 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -178,6 +178,8 @@
 extern unsigned int mmc_calc_max_discard(struct mmc_card *card);
 
 extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
+extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
+			      bool is_rel_write);
 extern int mmc_hw_reset(struct mmc_host *host);
 extern int mmc_hw_reset_check(struct mmc_host *host);
 extern int mmc_can_reset(struct mmc_card *card);
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index d5cada7..04ca56a 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -107,7 +107,7 @@
 
 config SND_SOC_MSM_QDSP6V2_INTF
 	bool "SoC Q6 audio driver for MSM8974"
-	depends on MSM_QDSP6_APR
+	depends on MSM_QDSP6_APRV2
 	help
 	 To add support for SoC audio on MSM8974.
 	 This will enable all the platform specific