Merge "video: msm: writeback: Stop providing buffers to mdp in stopping state" into msm-3.0
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 64877d1..b6570c7 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -6,6 +6,10 @@
 config GIC_NON_BANKED
 	bool
 
+config GIC_SECURE
+	bool
+	depends on ARM_GIC
+
 config ARM_VIC
 	bool
 
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index bb4d971..4e43cb2 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -156,7 +156,7 @@
 	return d->hwirq;
 }
 
-#ifdef CONFIG_CPU_V7
+#if defined(CONFIG_CPU_V7) && defined(CONFIG_GIC_SECURE)
 static const inline bool is_cpu_secure(void)
 {
 	unsigned int dscr;
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index d3ff90b..863a963 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -99,6 +99,8 @@
 CONFIG_DCC_TTY=y
 CONFIG_SPMI=y
 CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_MSM_QPNP=y
+CONFIG_MSM_QPNP_INT=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 7decf0a..6a5497d 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -208,6 +208,7 @@
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+CONFIG_TOUCHSCREEN_FT5X06=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=y
@@ -255,6 +256,7 @@
 CONFIG_FB_MSM_TRIPLE_BUFFER=y
 CONFIG_FB_MSM_MDP30=y
 CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
 CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 052c715..11c4224 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -208,6 +208,7 @@
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+CONFIG_TOUCHSCREEN_FT5X06=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=y
@@ -256,6 +257,7 @@
 CONFIG_FB_MSM_TRIPLE_BUFFER=y
 CONFIG_FB_MSM_MDP30=y
 CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
 CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index e865552..ab3f8da 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -74,6 +74,7 @@
 CONFIG_MSM_MODEM_8960=y
 CONFIG_MSM_LPASS_8960=y
 CONFIG_MSM_WCNSS_SSR_8960=y
+CONFIG_MSM_GSS_SSR_8064=y
 CONFIG_MSM_TZ_LOG=y
 CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_RPM_STATS_LOG=y
@@ -84,6 +85,7 @@
 CONFIG_MSM_DLOAD_MODE=y
 CONFIG_MSM_QDSS=y
 CONFIG_MSM_SLEEP_STATS=y
+CONFIG_MSM_DCVS=y
 CONFIG_STRICT_MEMORY_RWX=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 6104d65..75dff22 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -73,6 +73,7 @@
 CONFIG_MSM_MODEM_8960=y
 CONFIG_MSM_LPASS_8960=y
 CONFIG_MSM_WCNSS_SSR_8960=y
+CONFIG_MSM_GSS_SSR_8064=y
 CONFIG_MSM_TZ_LOG=y
 CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_RPM_STATS_LOG=y
@@ -84,6 +85,7 @@
 CONFIG_MSM_QDSS=y
 CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE=y
 CONFIG_MSM_SLEEP_STATS=y
+CONFIG_MSM_DCVS=y
 CONFIG_MSM_RTB=y
 CONFIG_MSM_RTB_SEPARATE_CPUS=y
 CONFIG_STRICT_MEMORY_RWX=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 71cda29..c9ce881 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -43,6 +43,7 @@
 # CONFIG_MSM_RESET_MODEM is not set
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_PIL_QDSP6V4=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 # CONFIG_MSM_SYSMON_COMM is not set
 CONFIG_MSM_MODEM_8960=y
@@ -201,8 +202,13 @@
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8960=y
 CONFIG_MFD_PM8018_CORE=y
+CONFIG_WCD9310_CODEC=y
 CONFIG_REGULATOR_PM8XXX=y
 CONFIG_REGULATOR_GPIO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_MDM9615=y
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index f5e1cec..551da73 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -14,6 +14,11 @@
 
 struct clock_event_device;
 
+struct local_timer_ops {
+	int  (*setup)(struct clock_event_device *);
+	void (*stop)(struct clock_event_device *);
+};
+
 /*
  * Setup a per-cpu timer, whether it be a local timer or dummy broadcast
  */
@@ -41,6 +46,11 @@
  */
 int local_timer_setup(struct clock_event_device *);
 
+/*
+ * Register a local timer driver
+ */
+int local_timer_register(struct local_timer_ops *);
+
 #else
 
 static inline int local_timer_setup(struct clock_event_device *evt)
@@ -51,6 +61,11 @@
 static inline void local_timer_stop(struct clock_event_device *evt)
 {
 }
+
+static inline int local_timer_register(struct local_timer_ops *ops)
+{
+	return -ENXIO;
+}
 #endif
 
 #endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ea64ba6..4471d90 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -498,6 +498,33 @@
 	clockevents_register_device(evt);
 }
 
+static struct local_timer_ops *lt_ops;
+
+#ifdef CONFIG_LOCAL_TIMERS
+int local_timer_register(struct local_timer_ops *ops)
+{
+	if (lt_ops)
+		return -EBUSY;
+
+	lt_ops = ops;
+	return 0;
+}
+#endif
+
+int __cpuinit __attribute__ ((weak)) local_timer_setup(struct clock_event_device *clk)
+{
+	if (lt_ops)
+		return lt_ops->setup(clk);
+
+	return -ENXIO;
+}
+
+void __attribute__ ((weak)) local_timer_stop(struct clock_event_device *clk)
+{
+	if (lt_ops)
+		lt_ops->stop(clk);
+}
+
 void __cpuinit percpu_timer_setup(void)
 {
 	unsigned int cpu = smp_processor_id();
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index cb7dd40..dbf1e6e 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -33,7 +33,7 @@
 /*
  * Enable the SCU
  */
-void __init scu_enable(void __iomem *scu_base)
+void scu_enable(void __iomem *scu_base)
 {
 	u32 scu_ctrl;
 
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 023d289..c9f5c29 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -250,6 +250,7 @@
 config ARCH_MSM9615
 	bool "MSM9615"
 	select ARM_GIC
+	select GIC_SECURE
 	select ARCH_MSM_CORTEX_A5
 	select CPU_V7
 	select MSM_V2_TLMM
@@ -262,6 +263,9 @@
 	select MULTI_IRQ_HANDLER
 	select MSM_PM8X60 if PM
 	select MSM_XO
+	select MSM_PIL
+	select MSM_QDSP6_APR
+	select MSM_AUDIO_QDSP6 if SND_SOC
 
 config ARCH_MSM8625
 	bool "MSM8625"
@@ -314,11 +318,13 @@
 config  ARCH_MSM_SCORPIONMP
 	select ARCH_MSM_SCORPION
 	select MSM_SMP
+	select HAVE_ARCH_HAS_CURRENT_TIMER
 	bool
 
 config  ARCH_MSM_KRAITMP
 	select ARCH_MSM_KRAIT
 	select MSM_SMP
+	select HAVE_ARCH_HAS_CURRENT_TIMER
 	bool
 
 config  ARCH_MSM_CORTEXMP
@@ -497,6 +503,14 @@
 	help
 	  Support for the Qualcomm MSM8625 Reference Design.
 
+config MACH_MSM8625_QRD7
+	depends on ARCH_MSM8625
+	depends on !MSM_STACKED_MEMORY
+	default y
+	bool "MSM8625 QRD7"
+	help
+	  Support for the Qualcomm MSM8625 Reference Design.
+
 config MACH_MSM7X30_SURF
        depends on ARCH_MSM7X30
        depends on !MSM_STACKED_MEMORY
@@ -1810,6 +1824,14 @@
 	 monitors WCNSS hardware watchdog interrupt lines and plugs WCNSS
 	 into the subsystem restart framework.
 
+config MSM_GSS_SSR_8064
+	bool "MSM 8064 GSS restart driver"
+	depends on (ARCH_APQ8064)
+	help
+	 This option enables the gps subsystem restart driver for APQ8064, which monitors
+	 gss hardware watchdog interrupt lines and plugs into the subsystem
+	 restart and PIL drivers.
+
 config SCORPION_Uni_45nm_BUG
 	bool "Scorpion Uni 45nm(SC45U): Workaround for ICIMVAU and BPIMVA"
 	depends on ARCH_MSM7X30 || (ARCH_QSD8X50 && MSM_SOC_REV_A)
@@ -2185,4 +2207,6 @@
 	  algorithm and the algorithm returns a frequency for the core which is
 	  passed to the frequency change driver.
 
+config HAVE_ARCH_HAS_CURRENT_TIMER
+	bool
 endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 6df96ad..f71cf6d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -192,6 +192,7 @@
 obj-$(CONFIG_MSM_MODEM_8960) += modem-8960.o
 obj-$(CONFIG_MSM_LPASS_8960) += lpass-8960.o
 obj-$(CONFIG_MSM_WCNSS_SSR_8960) += wcnss-ssr-8960.o
+obj-$(CONFIG_MSM_GSS_SSR_8064) += gss-8064.o
 
 ifdef CONFIG_CPU_IDLE
 	obj-$(CONFIG_ARCH_APQ8064) += cpuidle.o
@@ -233,6 +234,7 @@
 obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
 obj-$(CONFIG_MACH_MSM8625_SURF) +=  board-msm7x27a.o board-7627a-all.o
 obj-$(CONFIG_MACH_MSM8625_EVB) +=  board-qrd7627a.o board-7627a-all.o
+obj-$(CONFIG_MACH_MSM8625_QRD7) +=  board-qrd7627a.o board-7627a-all.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
 obj-$(CONFIG_ARCH_MSM7X30) += clock-local.o clock-7x30.o acpuclock-7x30.o
 obj-$(CONFIG_MACH_MSM7X25_SURF) += board-msm7x27.o devices-msm7x25.o
@@ -245,7 +247,7 @@
 obj-$(CONFIG_ARCH_MSM8960) += devices-8960.o
 obj-$(CONFIG_ARCH_APQ8064) += devices-8960.o devices-8064.o
 board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
-board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o devices-8930.o
+board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o devices-8930.o board-8930-gpu.o
 board-8064-all-objs += board-8064.o board-8064-pmic.o board-8064-storage.o board-8064-gpiomux.o board-8064-camera.o board-8064-display.o board-8064-gpu.o
 obj-$(CONFIG_MACH_MSM8960_SIM) += board-8960-all.o board-8960-regulator.o
 obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-8960-all.o board-8960-regulator.o
@@ -313,7 +315,7 @@
 
 obj-$(CONFIG_MSM_SLEEP_STATS) += msm_rq_stats.o idle_stats.o
 obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
-obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o
+obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o msm_dcvs_idle.o
 obj-$(CONFIG_MSM_SHOW_RESUME_IRQ) += msm_show_resume_irq.o
 obj-$(CONFIG_BT_MSM_PINTEST)  += btpintest.o
 obj-$(CONFIG_MSM_FAKE_BATTERY) += fish_battery.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 687033c..35e8eba 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -29,8 +29,9 @@
 #include <linux/sort.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
-#include <asm/mach-types.h>
 #include <mach/socinfo.h>
+#include <asm/mach-types.h>
+#include <asm/cpu.h>
 
 #include "smd_private.h"
 #include "acpuclock.h"
@@ -87,6 +88,7 @@
 	unsigned int	ahbclk_div;
 	int		vdd;
 	unsigned int	axiclk_khz;
+	unsigned long   lpj; /* loops_per_jiffy */
 	/* Pointers in acpu_freq_tbl[] for max up/down steppings. */
 	struct clkctl_acpu_speed *down[ACPU_PLL_END];
 	struct clkctl_acpu_speed *up[ACPU_PLL_END];
@@ -114,7 +116,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627 with CDMA capable modem */
@@ -128,7 +130,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 2, 133333, 2, 5, 160000 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 200000, 2, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627 with GSM capable modem - PLL2 @ 800 */
@@ -142,7 +144,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
 	{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627 with CDMA capable modem - PLL2 @ 800 */
@@ -156,7 +158,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 1, 133333, 2, 5, 160000 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 160000, 2, 6, 160000 },
 	{ 1, 800000, ACPU_PLL_2, 2, 0, 200000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -171,7 +173,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -186,7 +188,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -201,7 +203,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -216,7 +218,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 8625 PLL4 @ 1209MHz with GSM capable modem */
@@ -230,7 +232,7 @@
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
 	{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 8625 PLL4 @ 1209MHz with CDMA capable modem */
@@ -244,7 +246,7 @@
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 0, 604800, ACPU_PLL_4, 6, 1, 75600, 3, 6, 200000 },
 	{ 1, 1209600, ACPU_PLL_4, 6, 0, 151200, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -258,7 +260,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with GSM capable modem */
@@ -273,7 +275,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627a PLL2 @ 1200MHz with CDMA capable modem */
@@ -288,7 +290,7 @@
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 120000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 800000, ACPU_PLL_4, 6, 0, 100000, 3, 7, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with GSM capable modem */
@@ -303,7 +305,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7627aa PLL4 @ 1008MHz with CDMA capable modem */
@@ -318,7 +320,7 @@
 	{ 0, 504000, ACPU_PLL_4, 6, 1, 63000, 3, 6, 200000 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
 	{ 1, 1008000, ACPU_PLL_4, 6, 0, 126000, 3, 7, 200000},
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 /* 7625a PLL2 @ 1200MHz with GSM capable modem */
@@ -332,7 +334,7 @@
 	{ 0, 400000, ACPU_PLL_2, 2, 2, 50000, 3, 4, 122880 },
 	{ 1, 480000, ACPU_PLL_0, 4, 1, 60000, 3, 5, 122880 },
 	{ 1, 600000, ACPU_PLL_2, 2, 1, 75000, 3, 6, 200000 },
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}, {0, 0, 0, 0} }
 };
 
 #define PLL_CONFIG(m0, m1, m2, m4) { \
@@ -607,6 +609,16 @@
 
 		acpuclk_set_div(cur_s);
 		drv_state.current_speed = cur_s;
+		/* Re-adjust lpj for the new clock speed. */
+#ifdef CONFIG_SMP
+		for_each_possible_cpu(cpu) {
+			per_cpu(cpu_data, cpu).loops_per_jiffy =
+							cur_s->lpj;
+		}
+#endif
+		/* Adjust the global one */
+		loops_per_jiffy = cur_s->lpj;
+
 		mb();
 		udelay(50);
 	}
@@ -790,6 +802,27 @@
 	return found_khz;
 }
 
+static void __init 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 void __init precompute_stepping(void)
 {
 	int i, step_idx;
@@ -882,6 +915,7 @@
 	acpuclk_7627_data.wait_for_irq_khz = find_wait_for_irq_khz();
 	precompute_stepping();
 	acpuclk_hw_init();
+	lpj_init();
 	print_acpu_freq_tbl();
 	acpuclk_register(&acpuclk_7627_data);
 
diff --git a/arch/arm/mach-msm/acpuclock-7x30.c b/arch/arm/mach-msm/acpuclock-7x30.c
index 598b7c5..54d2aa9 100644
--- a/arch/arm/mach-msm/acpuclock-7x30.c
+++ b/arch/arm/mach-msm/acpuclock-7x30.c
@@ -76,6 +76,7 @@
 	unsigned int	vdd_mv;
 	unsigned int	vdd_raw;
 	struct pll	*pll_rate;
+	unsigned long	lpj; /* loops_per_jiffy */
 };
 
 static struct clock_state drv_state = { 0 };
@@ -258,6 +259,7 @@
 	/* Perform the frequency switch */
 	acpuclk_set_src(tgt_s);
 	drv_state.current_speed = tgt_s;
+	loops_per_jiffy = tgt_s->lpj;
 
 	if (tgt_s->src == PLL_2 && strt_s->src == PLL_2)
 		clk_disable(acpuclk_sources[backup_s->src]);
@@ -390,6 +392,19 @@
 	return;
 }
 
+/* Initalize the lpj field in the acpu_freq_tbl. */
+static void __init lpj_init(void)
+{
+	int i;
+	const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
+
+	for (i = 0; acpu_freq_tbl[i].acpu_clk_khz; i++) {
+		acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
+						base_clk->acpu_clk_khz,
+						acpu_freq_tbl[i].acpu_clk_khz);
+	}
+}
+
 #ifdef CONFIG_CPU_FREQ_MSM
 static struct cpufreq_frequency_table cpufreq_tbl[ARRAY_SIZE(acpu_freq_tbl)];
 
@@ -464,6 +479,7 @@
 	pll2_fixup();
 	populate_plls();
 	acpuclk_hw_init();
+	lpj_init();
 	setup_cpufreq_table();
 	acpuclk_register(&acpuclk_7x30_data);
 
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 2908025..a436f41 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -30,16 +30,18 @@
 
 #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
 /* prim = 1366 x 768 x 3(bpp) x 3(pages) */
-#define MSM_FB_PRIM_BUF_SIZE roundup(1376 * 768 * 4 * 3, 0x10000)
+#define MSM_FB_PRIM_BUF_SIZE roundup(1920 * 1080 * 4 * 3, 0x10000)
 #else
 /* prim = 1366 x 768 x 3(bpp) x 2(pages) */
-#define MSM_FB_PRIM_BUF_SIZE roundup(1376 * 768 * 4 * 2, 0x10000)
+#define MSM_FB_PRIM_BUF_SIZE roundup(1920 * 1080 * 4 * 2, 0x10000)
 #endif
 
 #ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-#define MSM_FB_EXT_BUF_SIZE	(1920 * 1088 * 2 * 1) /* 2 bpp x 1 page */
+#define MSM_FB_EXT_BUF_SIZE \
+		(roundup((1920 * 1088 * 2), 4096) * 1) /* 2 bpp x 1 page */
 #elif defined(CONFIG_FB_MSM_TVOUT)
-#define MSM_FB_EXT_BUF_SIZE (720 * 576 * 2 * 2) /* 2 bpp x 2 pages */
+#define MSM_FB_EXT_BUF_SIZE \
+		(roundup((720 * 576 * 2), 4096) * 2) /* 2 bpp x 2 pages */
 #else
 #define MSM_FB_EXT_BUF_SIZE	0
 #endif
@@ -71,6 +73,8 @@
 #define HDMI_PANEL_NAME "hdmi_msm"
 #define TVOUT_PANEL_NAME "tvout_msm"
 
+static void set_mdp_clocks_for_wuxga(void);
+
 static int msm_fb_detect_panel(const char *name)
 {
 	u32 version;
@@ -101,9 +105,13 @@
 	}
 
 	if (!strncmp(name, HDMI_PANEL_NAME,
-		strnlen(HDMI_PANEL_NAME,
-			PANEL_NAME_MAX_LEN)))
+			strnlen(HDMI_PANEL_NAME,
+				PANEL_NAME_MAX_LEN))) {
+		if (hdmi_is_primary)
+			set_mdp_clocks_for_wuxga();
 		return 0;
+	}
+
 
 	return -ENODEV;
 }
@@ -637,16 +645,6 @@
 	},
 };
 
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static struct msm_bus_vectors dtv_bus_def_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 2000000000,
-		.ib = 2000000000,
-	},
-};
-#else
 static struct msm_bus_vectors dtv_bus_def_vectors[] = {
 	{
 		.src = MSM_BUS_MASTER_MDP_PORT0,
@@ -655,7 +653,6 @@
 		.ib = 707616000 * 2,
 	},
 };
-#endif
 
 static struct msm_bus_paths dtv_bus_scale_usecases[] = {
 	{
@@ -911,3 +908,56 @@
 	platform_device_register(&hdmi_msm_device);
 	msm_fb_register_device("dtv", &dtv_pdata);
 }
+
+/**
+ * Set MDP clocks to high frequency to avoid DSI underflow
+ * when using high resolution 1200x1920 WUXGA panels
+ */
+static void set_mdp_clocks_for_wuxga(void)
+{
+	int i;
+
+	mdp_ui_vectors[0].ab = 2000000000;
+	mdp_ui_vectors[0].ib = 2000000000;
+	mdp_vga_vectors[0].ab = 2000000000;
+	mdp_vga_vectors[0].ib = 2000000000;
+	mdp_720p_vectors[0].ab = 2000000000;
+	mdp_720p_vectors[0].ib = 2000000000;
+	mdp_1080p_vectors[0].ab = 2000000000;
+	mdp_1080p_vectors[0].ib = 2000000000;
+
+	mdp_pdata.mdp_core_clk_rate = 200000000;
+
+	for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
+		mdp_core_clk_rate_table[i] = 200000000;
+
+	if (hdmi_is_primary) {
+		dtv_bus_def_vectors[0].ab = 2000000000;
+		dtv_bus_def_vectors[0].ib = 2000000000;
+	}
+}
+
+void __init apq8064_set_display_params(char *prim_panel, char *ext_panel)
+{
+	if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
+		strlcpy(msm_fb_pdata.prim_panel_name, prim_panel,
+			PANEL_NAME_MAX_LEN);
+		pr_debug("msm_fb_pdata.prim_panel_name %s\n",
+			msm_fb_pdata.prim_panel_name);
+
+		if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
+			HDMI_PANEL_NAME, strnlen(HDMI_PANEL_NAME,
+				PANEL_NAME_MAX_LEN))) {
+			pr_debug("HDMI is the primary display by"
+				" boot parameter\n");
+			hdmi_is_primary = 1;
+			set_mdp_clocks_for_wuxga();
+		}
+	}
+	if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
+		strlcpy(msm_fb_pdata.ext_panel_name, ext_panel,
+			PANEL_NAME_MAX_LEN);
+		pr_debug("msm_fb_pdata.ext_panel_name %s\n",
+			msm_fb_pdata.ext_panel_name);
+	}
+}
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index b52004a..cd8fba5 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -214,6 +214,7 @@
 	.nonremovable	= 1,
 	.pin_data	= &mmc_slot_pin_data[SDCC1],
 	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
+	.uhs_caps	= MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50,
 };
 static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
 #else
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 061966c..54d68d3 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -432,8 +432,27 @@
 		apq8064_reserve_info.bank_size);
 }
 
+static char prim_panel_name[PANEL_NAME_MAX_LEN];
+static char ext_panel_name[PANEL_NAME_MAX_LEN];
+static int __init prim_display_setup(char *param)
+{
+	if (strnlen(param, PANEL_NAME_MAX_LEN))
+		strlcpy(prim_panel_name, param, PANEL_NAME_MAX_LEN);
+	return 0;
+}
+early_param("prim_display", prim_display_setup);
+
+static int __init ext_display_setup(char *param)
+{
+	if (strnlen(param, PANEL_NAME_MAX_LEN))
+		strlcpy(ext_panel_name, param, PANEL_NAME_MAX_LEN);
+	return 0;
+}
+early_param("ext_display", ext_display_setup);
+
 static void __init apq8064_reserve(void)
 {
+	apq8064_set_display_params(prim_panel_name, ext_panel_name);
 	reserve_info = &apq8064_reserve_info;
 	locate_unstable_memory();
 	msm_reserve();
@@ -1757,6 +1776,8 @@
 #ifdef CONFIG_MSM_RTB
 	&msm_rtb_device,
 #endif
+	&apq8064_cpu_idle_device,
+	&apq8064_msm_gov_device,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index c19a039..938d2ea 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -73,6 +73,8 @@
 void apq8064_allocate_fb_region(void);
 void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
 uint32_t apq8064_rpm_get_swfi_latency(void);
+void __init apq8064_set_display_params(char *prim_panel, char *ext_panel);
+extern char hdmi_is_primary;
 
 void apq8064_init_gpu(void);
 void apq8064_pm8xxx_gpio_mpp_init(void);
diff --git a/arch/arm/mach-msm/board-8930-gpu.c b/arch/arm/mach-msm/board-8930-gpu.c
new file mode 100644
index 0000000..a5157038
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-gpu.c
@@ -0,0 +1,163 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/msm_kgsl.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+
+#include "devices.h"
+#include "board-8930.h"
+
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors grp3d_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+static struct msm_bus_vectors grp3d_low_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(2000),
+	},
+};
+
+static struct msm_bus_vectors grp3d_nominal_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(3200),
+	},
+};
+
+static struct msm_bus_vectors grp3d_max_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_GRAPHICS_3D,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = KGSL_CONVERT_TO_MBPS(3200),
+	},
+};
+
+static struct msm_bus_paths grp3d_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(grp3d_init_vectors),
+		grp3d_init_vectors,
+	},
+	{
+		ARRAY_SIZE(grp3d_low_vectors),
+		grp3d_low_vectors,
+	},
+	{
+		ARRAY_SIZE(grp3d_nominal_vectors),
+		grp3d_nominal_vectors,
+	},
+	{
+		ARRAY_SIZE(grp3d_max_vectors),
+		grp3d_max_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata grp3d_bus_scale_pdata = {
+	grp3d_bus_scale_usecases,
+	ARRAY_SIZE(grp3d_bus_scale_usecases),
+	.name = "grp3d",
+};
+#endif
+
+static struct resource kgsl_3d0_resources[] = {
+	{
+		.name = KGSL_3D0_REG_MEMORY,
+		.start = 0x04300000, /* GFX3D address */
+		.end = 0x0431ffff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.name = KGSL_3D0_IRQ,
+		.start = GFX3D_IRQ,
+		.end = GFX3D_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static const char *kgsl_3d0_iommu0_ctx_names[] = {
+	"gfx3d_user",
+	/* priv_ctx goes here */
+};
+
+static struct kgsl_device_iommu_data kgsl_3d0_iommu_data[] = {
+	{
+		.iommu_ctx_names = kgsl_3d0_iommu0_ctx_names,
+		.iommu_ctx_count = ARRAY_SIZE(kgsl_3d0_iommu0_ctx_names),
+		.physstart = 0x07C00000,
+		.physend = 0x07C00000 + SZ_1M - 1,
+	},
+};
+
+static struct kgsl_device_platform_data kgsl_3d0_pdata = {
+	.pwrlevel = {
+		{
+			.gpu_freq = 200000000,
+			.bus_freq = 3,
+			.io_fraction = 0,
+		},
+		{
+			.gpu_freq = 200000000,
+			.bus_freq = 2,
+			.io_fraction = 33,
+		},
+		{
+			.gpu_freq = 200000000,
+			.bus_freq = 1,
+			.io_fraction = 100,
+		},
+		{
+			.gpu_freq = 27000000,
+			.bus_freq = 0,
+		},
+	},
+	.init_level = 0,
+	.num_levels = 4,
+	.set_grp_async = NULL,
+	.idle_timeout = 0x1FFFFFFF,
+	.nap_allowed = false,
+	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
+#ifdef CONFIG_MSM_BUS_SCALING
+	.bus_scale_table = &grp3d_bus_scale_pdata,
+#endif
+	.iommu_data = kgsl_3d0_iommu_data,
+	.iommu_count = ARRAY_SIZE(kgsl_3d0_iommu_data),
+};
+
+static struct platform_device device_kgsl_3d0 = {
+	.name = "kgsl-3d0",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(kgsl_3d0_resources),
+	.resource = kgsl_3d0_resources,
+	.dev = {
+		.platform_data = &kgsl_3d0_pdata,
+	},
+};
+
+void __init msm8930_init_gpu(void)
+{
+	platform_device_register(&device_kgsl_3d0);
+}
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 9dcbb67..f2bd41b 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -952,15 +952,17 @@
 {
 #ifdef CONFIG_MSM_BUS_SCALING
 	msm_bus_rpm_set_mt_mask();
-	msm_bus_8960_apps_fabric_pdata.rpm_enabled = 1;
-	msm_bus_8960_sys_fabric_pdata.rpm_enabled = 1;
-	msm_bus_8960_mm_fabric_pdata.rpm_enabled = 1;
-	msm_bus_apps_fabric.dev.platform_data =
-		&msm_bus_8960_apps_fabric_pdata;
-	msm_bus_sys_fabric.dev.platform_data = &msm_bus_8960_sys_fabric_pdata;
-	msm_bus_mm_fabric.dev.platform_data = &msm_bus_8960_mm_fabric_pdata;
-	msm_bus_sys_fpb.dev.platform_data = &msm_bus_8960_sys_fpb_pdata;
-	msm_bus_cpss_fpb.dev.platform_data = &msm_bus_8960_cpss_fpb_pdata;
+	msm_bus_8930_apps_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8930_sys_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8930_mm_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8930_apps_fabric.dev.platform_data =
+		&msm_bus_8930_apps_fabric_pdata;
+	msm_bus_8930_sys_fabric.dev.platform_data =
+		&msm_bus_8930_sys_fabric_pdata;
+	msm_bus_8930_mm_fabric.dev.platform_data =
+		&msm_bus_8930_mm_fabric_pdata;
+	msm_bus_8930_sys_fpb.dev.platform_data = &msm_bus_8930_sys_fpb_pdata;
+	msm_bus_8930_cpss_fpb.dev.platform_data = &msm_bus_8930_cpss_fpb_pdata;
 #endif
 }
 
@@ -1783,7 +1785,6 @@
 #endif
 	&android_pmem_audio_device,
 #endif
-	&msm_device_vidc,
 	&msm_device_bam_dmux,
 	&msm_fm_platform_init,
 
@@ -1812,6 +1813,13 @@
 #ifdef CONFIG_MSM_RTB
 	&msm_rtb_device,
 #endif
+	&msm8930_cpu_idle_device,
+	&msm8930_msm_gov_device,
+	&msm_bus_8930_apps_fabric,
+	&msm_bus_8930_sys_fabric,
+	&msm_bus_8930_mm_fabric,
+	&msm_bus_8930_sys_fpb,
+	&msm_bus_8930_cpss_fpb,
 };
 
 static struct platform_device *cdp_devices[] __initdata = {
@@ -1832,11 +1840,6 @@
 	&msm_cpudai_auxpcm_tx,
 	&msm_cpu_fe,
 	&msm_stub_codec,
-	&msm_kgsl_3d0,
-#ifdef CONFIG_MSM_KGSL_2D
-	&msm_kgsl_2d0,
-	&msm_kgsl_2d1,
-#endif
 #ifdef CONFIG_MSM_GEMINI
 	&msm8960_gemini_device,
 #endif
@@ -1853,11 +1856,6 @@
 	&msm_cpudai_incall_record_rx,
 	&msm_cpudai_incall_record_tx,
 	&msm_pcm_hostless,
-	&msm_bus_apps_fabric,
-	&msm_bus_sys_fabric,
-	&msm_bus_mm_fabric,
-	&msm_bus_sys_fpb,
-	&msm_bus_cpss_fpb,
 };
 
 static void __init msm8930_i2c_init(void)
@@ -1878,17 +1876,6 @@
 					&msm8960_i2c_qup_gsbi12_pdata;
 }
 
-static void __init msm8930_gfx_init(void)
-{
-	uint32_t soc_platform_version = socinfo_get_version();
-	if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
-		struct kgsl_device_platform_data *kgsl_3d0_pdata =
-				msm_kgsl_3d0.dev.platform_data;
-		kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
-		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
-	}
-}
-
 static struct msm_cpuidle_state msm_cstates[] __initdata = {
 	{0, 0, "C0", "WFI",
 		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
@@ -2184,7 +2171,7 @@
 	if (msm_xo_init())
 		pr_err("Failed to initialize XO votes\n");
 	platform_device_register(&msm8930_device_rpm_regulator);
-	msm_clock_init(&msm8960_clock_init_data);
+	msm_clock_init(&msm8930_clock_init_data);
 	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
 	msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
 	msm8930_init_gpiomux();
@@ -2203,13 +2190,14 @@
 	msm8930_init_pmic();
 #endif
 	msm8930_i2c_init();
-	msm8930_gfx_init();
+	msm8930_init_gpu();
 	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
 	msm_spm_l2_init(msm_spm_l2_data);
 	msm8930_init_buses();
 	platform_add_devices(msm_footswitch_devices,
 		msm_num_footswitch_devices);
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	msm8930_add_vidc_device();
 	/*
 	 * TODO: When physical 8930/PM8038 hardware becomes
 	 * available, remove this block or add the config
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index cefaff5..45fe40f 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -109,6 +109,7 @@
 void msm8930_init_cam(void);
 void msm8930_init_fb(void);
 void msm8930_init_pmic(void);
+extern void msm8930_add_vidc_device(void);
 
 /*
  * TODO: When physical 8930/PM8038 hardware becomes
@@ -125,6 +126,7 @@
 void msm8930_allocate_fb_region(void);
 void msm8930_pm8038_gpio_mpp_init(void);
 void msm8930_mdp_writeback(struct memtype_reserve *reserve_table);
+void __init msm8930_init_gpu(void);
 
 #define PLATFORM_IS_CHARM25() \
 	(machine_is_msm8930_cdp() && \
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index e2ba303..db0bbff 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -140,7 +140,7 @@
 #define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
 #define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
 #define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
-#define MSM_ION_QSECOM_SIZE	0x300000 /* (3MB) */
+#define MSM_ION_QSECOM_SIZE	0x600000 /* (6MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
 #define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
 #define MSM_ION_HEAP_NUM	8
@@ -2190,6 +2190,8 @@
 #ifdef CONFIG_MSM_RTB
 	&msm_rtb_device,
 #endif
+	&msm8960_cpu_idle_device,
+	&msm8960_msm_gov_device,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-9615-gpiomux.c b/arch/arm/mach-msm/board-9615-gpiomux.c
index ea8caf5..e61f001 100644
--- a/arch/arm/mach-msm/board-9615-gpiomux.c
+++ b/arch/arm/mach-msm/board-9615-gpiomux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -79,6 +79,21 @@
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
+static struct gpiomux_setting cdc_mclk = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct msm_gpiomux_config msm9615_audio_codec_configs[] __initdata = {
+	{
+		.gpio = 24,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &cdc_mclk,
+		},
+	},
+};
+
 static struct msm_gpiomux_config msm9615_sdcc2_configs[] __initdata = {
 	{
 		/* SDC2_DATA_0 */
@@ -271,6 +286,8 @@
 	msm_gpiomux_install(msm9615_ltc4088_charger_config,
 			ARRAY_SIZE(msm9615_ltc4088_charger_config));
 #endif
+	msm_gpiomux_install(msm9615_audio_codec_configs,
+			ARRAY_SIZE(msm9615_audio_codec_configs));
 
 	return 0;
 }
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index 11d35f4..dd83d6f 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -74,10 +74,22 @@
 };
 VREG_CONSUMERS(S2) = {
 	REGULATOR_SUPPLY("8018_s2",		NULL),
+	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"tabla2x-slim"),
+	REGULATOR_SUPPLY("VDDD_CDC_D",		"tabla-slim"),
+	REGULATOR_SUPPLY("VDDD_CDC_D",		"tabla2x-slim"),
 };
 VREG_CONSUMERS(S3) = {
 	REGULATOR_SUPPLY("8018_s3",		NULL),
 	REGULATOR_SUPPLY("wlan_vreg",		"wlan_ar6000_pm_dev"),
+	REGULATOR_SUPPLY("CDC_VDD_CP",		"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDD_CP",		"tabla2x-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_RX",		"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_RX",		"tabla2x-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_TX",		"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_TX",		"tabla2x-slim"),
+	REGULATOR_SUPPLY("VDDIO_CDC",		"tabla-slim"),
+	REGULATOR_SUPPLY("VDDIO_CDC",		"tabla2x-slim"),
 };
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8018_s4",		NULL),
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 8fe55ff..40cd9ea 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -15,6 +15,10 @@
 #include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/slimbus/slimbus.h>
+#ifdef CONFIG_WCD9310_CODEC
+#include <linux/mfd/wcd9xxx/core.h>
+#include <linux/mfd/wcd9xxx/pdata.h>
+#endif
 #include <linux/msm_ssbi.h>
 #include <linux/memblock.h>
 #include <linux/usb/android.h>
@@ -30,9 +34,11 @@
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 #include <mach/gpio.h>
+#include <mach/socinfo.h>
 #include <mach/msm_spi.h>
 #include <mach/msm_bus_board.h>
 #include <mach/msm_xo.h>
+#include <mach/dma.h>
 #include "timer.h"
 #include "devices.h"
 #include "board-9615.h"
@@ -231,8 +237,96 @@
 #endif
 }
 
+#ifdef CONFIG_WCD9310_CODEC
+
+#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+
+/* Micbias setting is based on 8660 CDP/MTP/FLUID requirement
+ * 4 micbiases are used to power various analog and digital
+ * microphones operating at 1800 mV. Technically, all micbiases
+ * can source from single cfilter since all microphones operate
+ * at the same voltage level. The arrangement below is to make
+ * sure all cfilters are exercised. LDO_H regulator ouput level
+ * does not need to be as high as 2.85V. It is choosen for
+ * microphone sensitivity purpose.
+ */
+
+static struct wcd9xxx_pdata tabla20_platform_data = {
+	.slimbus_slave_device = {
+		.name = "tabla-slave",
+		.e_addr = {0, 0, 0x60, 0, 0x17, 2},
+	},
+	.irq = 85,
+	.irq_base = TABLA_INTERRUPT_BASE,
+	.num_irqs = NR_WCD9XXX_IRQS,
+	.reset_gpio = 84,
+	.micbias = {
+		.ldoh_v = TABLA_LDOH_2P85_V,
+		.cfilt1_mv = 1800,
+		.cfilt2_mv = 1800,
+		.cfilt3_mv = 1800,
+		.bias1_cfilt_sel = TABLA_CFILT1_SEL,
+		.bias2_cfilt_sel = TABLA_CFILT2_SEL,
+		.bias3_cfilt_sel = TABLA_CFILT3_SEL,
+		.bias4_cfilt_sel = TABLA_CFILT3_SEL,
+	},
+	.regulator = {
+	{
+		.name = "CDC_VDD_CP",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.optimum_uA = WCD9XXX_CDC_VDDA_CP_CUR_MAX,
+	},
+	{
+		.name = "CDC_VDDA_RX",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.optimum_uA = WCD9XXX_CDC_VDDA_RX_CUR_MAX,
+	},
+	{
+		.name = "CDC_VDDA_TX",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.optimum_uA = WCD9XXX_CDC_VDDA_TX_CUR_MAX,
+	},
+	{
+		.name = "VDDIO_CDC",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.optimum_uA = WCD9XXX_VDDIO_CDC_CUR_MAX,
+	},
+	{
+		.name = "VDDD_CDC_D",
+		.min_uV = 1225000,
+		.max_uV = 1225000,
+		.optimum_uA = WCD9XXX_VDDD_CDC_D_CUR_MAX,
+	},
+	{
+		.name = "CDC_VDDA_A_1P2V",
+		.min_uV = 1225000,
+		.max_uV = 1225000,
+		.optimum_uA = WCD9XXX_VDDD_CDC_A_CUR_MAX,
+	},
+	},
+};
+
+static struct slim_device msm_slim_tabla20 = {
+	.name = "tabla2x-slim",
+	.e_addr = {0, 1, 0x60, 0, 0x17, 2},
+	.dev = {
+		.platform_data = &tabla20_platform_data,
+	},
+};
+#endif
+
 static struct slim_boardinfo msm_slim_devices[] = {
 	/* add slimbus slaves as needed */
+#ifdef CONFIG_WCD9310_CODEC
+	{
+		.bus_num = 1,
+		.slim_slave = &msm_slim_tabla20,
+	},
+#endif
 };
 
 static struct msm_spi_platform_data msm9615_qup_spi_gsbi3_pdata = {
@@ -545,6 +639,26 @@
 	&msm_device_rng,
 #endif
 
+	&msm_pcm,
+	&msm_multi_ch_pcm,
+	&msm_pcm_routing,
+	&msm_cpudai0,
+	&msm_cpudai1,
+	&msm_cpudai_bt_rx,
+	&msm_cpudai_bt_tx,
+	&msm_cpu_fe,
+	&msm_stub_codec,
+	&msm_voice,
+	&msm_voip,
+	&msm_pcm_hostless,
+	&msm_cpudai_afe_01_rx,
+	&msm_cpudai_afe_01_tx,
+	&msm_cpudai_afe_02_rx,
+	&msm_cpudai_afe_02_tx,
+	&msm_pcm_afe,
+	&msm_cpudai_auxpcm_rx,
+	&msm_cpudai_auxpcm_tx,
+
 #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
 		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
 	&msm9615_qcrypto_device,
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index bf1a4c5..950815a 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -44,6 +44,245 @@
 
 early_param("fb_size", fb_size_setup);
 
+static uint32_t lcdc_truly_gpio_initialized;
+static struct regulator_bulk_data regs_truly_lcdc[] = {
+	{ .supply = "rfrx1",   .min_uV = 1800000, .max_uV = 1800000 },
+};
+
+#define SKU3_LCDC_GPIO_DISPLAY_RESET	90
+#define SKU3_LCDC_GPIO_SPI_MOSI		19
+#define SKU3_LCDC_GPIO_SPI_CLK		20
+#define SKU3_LCDC_GPIO_SPI_CS0_N	21
+#define SKU3_LCDC_LCD_CAMERA_LDO_2V8	35  /*LCD_CAMERA_LDO_2V8*/
+#define SKU3_LCDC_LCD_CAMERA_LDO_1V8	34  /*LCD_CAMERA_LDO_1V8*/
+#define SKU3_1_LCDC_LCD_CAMERA_LDO_1V8	58  /*LCD_CAMERA_LDO_1V8*/
+
+static uint32_t lcdc_truly_gpio_table[] = {
+	19,
+	20,
+	21,
+	89,
+	90,
+};
+
+static char *lcdc_gpio_name_table[5] = {
+	"spi_mosi",
+	"spi_clk",
+	"spi_cs",
+	"gpio_bkl_en",
+	"gpio_disp_reset",
+};
+
+static int lcdc_truly_gpio_init(void)
+{
+	int i;
+	int rc = 0;
+
+	if (!lcdc_truly_gpio_initialized) {
+		for (i = 0; i < ARRAY_SIZE(lcdc_truly_gpio_table); i++) {
+			rc = gpio_request(lcdc_truly_gpio_table[i],
+				lcdc_gpio_name_table[i]);
+			if (rc < 0) {
+				pr_err("Error request gpio %s\n",
+					lcdc_gpio_name_table[i]);
+				goto truly_gpio_fail;
+			}
+			rc = gpio_tlmm_config(GPIO_CFG(lcdc_truly_gpio_table[i],
+				0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+				GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+			if (rc < 0) {
+				pr_err("Error config lcdc gpio:%d\n",
+					lcdc_truly_gpio_table[i]);
+				goto truly_gpio_fail;
+			}
+			rc = gpio_direction_output(lcdc_truly_gpio_table[i], 0);
+			if (rc < 0) {
+				pr_err("Error direct lcdc gpio:%d\n",
+					lcdc_truly_gpio_table[i]);
+				goto truly_gpio_fail;
+			}
+		}
+
+			lcdc_truly_gpio_initialized = 1;
+	}
+
+	return rc;
+
+truly_gpio_fail:
+	for (; i >= 0; i--) {
+		pr_err("Freeing GPIO: %d", lcdc_truly_gpio_table[i]);
+		gpio_free(lcdc_truly_gpio_table[i]);
+	}
+
+	lcdc_truly_gpio_initialized = 0;
+	return rc;
+}
+
+
+void sku3_lcdc_lcd_camera_power_init(void)
+{
+	int rc = 0;
+	u32 socinfo = socinfo_get_platform_type();
+
+	  /* LDO_EXT2V8 */
+	if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_2V8, "lcd_camera_ldo_2v8")) {
+		pr_err("failed to request gpio lcd_camera_ldo_2v8\n");
+		return;
+	}
+
+	rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0,
+		GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+		GPIO_CFG_ENABLE);
+
+	if (rc < 0) {
+		pr_err("%s:unable to enable lcd_camera_ldo_2v8!\n", __func__);
+		goto fail_gpio2;
+	}
+
+	/* LDO_EVT1V8 */
+	if (socinfo == 0x0B) {
+		if (gpio_request(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
+				"lcd_camera_ldo_1v8")) {
+			pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
+			goto fail_gpio1;
+		}
+
+		rc = gpio_tlmm_config(GPIO_CFG(SKU3_LCDC_LCD_CAMERA_LDO_1V8, 0,
+			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+			GPIO_CFG_ENABLE);
+
+		if (rc < 0) {
+			pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
+				__func__);
+			goto fail_gpio1;
+		}
+	} else if (socinfo == 0x0F) {
+		if (gpio_request(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+				"lcd_camera_ldo_1v8")) {
+			pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
+			goto fail_gpio1;
+		}
+
+		rc = gpio_tlmm_config(GPIO_CFG(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+			0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+			GPIO_CFG_ENABLE);
+
+		if (rc < 0) {
+			pr_err("%s: unable to enable lcdc_camera_ldo_1v8!\n",
+				__func__);
+			goto fail_gpio1;
+		}
+	}
+
+	rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_truly_lcdc),
+			regs_truly_lcdc);
+	if (rc)
+		pr_err("%s: could not get regulators: %d\n", __func__, rc);
+
+	rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_truly_lcdc),
+			regs_truly_lcdc);
+	if (rc)
+		pr_err("%s: could not set voltages: %d\n", __func__, rc);
+
+	return;
+
+fail_gpio1:
+	if (socinfo == 0x0B)
+		gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_1V8);
+	else if (socinfo == 0x0F)
+		gpio_free(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8);
+fail_gpio2:
+	gpio_free(SKU3_LCDC_LCD_CAMERA_LDO_2V8);
+	return;
+}
+
+int sku3_lcdc_lcd_camera_power_onoff(int on)
+{
+	int rc = 0;
+	u32 socinfo = socinfo_get_platform_type();
+
+	if (on) {
+		if (socinfo == 0x0B)
+			gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
+				1);
+		else if (socinfo == 0x0F)
+			gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+				1);
+
+		gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 1);
+
+		rc = regulator_bulk_enable(ARRAY_SIZE(regs_truly_lcdc),
+				regs_truly_lcdc);
+		if (rc)
+			pr_err("%s: could not enable regulators: %d\n",
+				__func__, rc);
+	} else {
+		if (socinfo == 0x0B)
+			gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
+				0);
+		else if (socinfo == 0x0F)
+			gpio_set_value_cansleep(SKU3_1_LCDC_LCD_CAMERA_LDO_1V8,
+				0);
+
+		gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_2V8, 0);
+
+		rc = regulator_bulk_disable(ARRAY_SIZE(regs_truly_lcdc),
+				regs_truly_lcdc);
+		if (rc)
+			pr_err("%s: could not disable regulators: %d\n",
+				__func__, rc);
+	}
+
+	return rc;
+}
+
+static int sku3_lcdc_power_save(int on)
+{
+	int rc = 0;
+
+	if (on) {
+		sku3_lcdc_lcd_camera_power_onoff(1);
+		rc = lcdc_truly_gpio_init();
+		if (rc < 0) {
+			pr_err("%s(): Truly GPIO initializations failed",
+				__func__);
+			return rc;
+		}
+
+		if (lcdc_truly_gpio_initialized) {
+			/*LCD reset*/
+			gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
+			msleep(20);
+			gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
+			msleep(20);
+			gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 1);
+			msleep(20);
+		}
+	} else {
+		/* pull down LCD IO to avoid current leakage */
+		gpio_set_value(SKU3_LCDC_GPIO_SPI_MOSI, 0);
+		gpio_set_value(SKU3_LCDC_GPIO_SPI_CLK, 0);
+		gpio_set_value(SKU3_LCDC_GPIO_SPI_CS0_N, 0);
+		gpio_set_value(SKU3_LCDC_GPIO_DISPLAY_RESET, 0);
+
+		sku3_lcdc_lcd_camera_power_onoff(0);
+	}
+	return rc;
+}
+
+static struct msm_panel_common_pdata lcdc_truly_panel_data = {
+	.panel_config_gpio = NULL,
+	.gpio_num	  = lcdc_truly_gpio_table,
+};
+
+static struct platform_device lcdc_truly_panel_device = {
+	.name   = "lcdc_truly_hvga_ips3p2335_pt",
+	.id     = 0,
+	.dev    = {
+		.platform_data = &lcdc_truly_panel_data,
+	}
+};
+
 static struct regulator_bulk_data regs_lcdc[] = {
 	{ .supply = "gp2",   .min_uV = 2850000, .max_uV = 2850000 },
 	{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
@@ -176,9 +415,21 @@
 	return ret;
 }
 
+
+static int msm_lcdc_power_save(int on)
+{
+	int rc = 0;
+	if (machine_is_msm7627a_qrd3())
+		rc = sku3_lcdc_power_save(on);
+	else
+		rc = msm_fb_lcdc_power_save(on);
+
+	return rc;
+}
+
 static struct lcdc_platform_data lcdc_pdata = {
 	.lcdc_gpio_config = NULL,
-	.lcdc_power_save   = msm_fb_lcdc_power_save,
+	.lcdc_power_save   = msm_lcdc_power_save,
 };
 
 static int lcd_panel_spi_gpio_num[] = {
@@ -226,6 +477,9 @@
 	} else if (machine_is_msm7627a_qrd1()) {
 		if (!strncmp(name, "mipi_video_truly_wvga", 21))
 			ret = 0;
+	} else if (machine_is_msm7627a_qrd3()) {
+		if (!strncmp(name, "lcdc_truly_hvga_ips3p2335_pt", 28))
+			ret = 0;
 	} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
 		if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
 			ret = 0;
@@ -332,6 +586,11 @@
 	&mipi_dsi_truly_panel_device,
 };
 
+static struct platform_device *qrd3_fb_devices[] __initdata = {
+	&msm_fb_device,
+	&lcdc_truly_panel_device,
+};
+
 static struct platform_device *evb_fb_devices[] __initdata = {
 	&msm_fb_device,
 	&mipi_dsi_NT35510_panel_device,
@@ -836,7 +1095,7 @@
 
 #define MDP_303_VSYNC_GPIO 97
 
-#ifdef CONFIG_FB_MSM_MDP303
+#ifdef CONFIG_FB_MSM_MIPI_DSI
 static struct mipi_dsi_platform_data mipi_dsi_pdata = {
 	.vsync_gpio		= MDP_303_VSYNC_GPIO,
 	.dsi_power_save		= mipi_dsi_panel_power,
@@ -853,17 +1112,19 @@
 	else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		platform_add_devices(evb_fb_devices,
 				ARRAY_SIZE(evb_fb_devices));
-	else if (machine_is_msm7627a_qrd3())
-		return;
-	else
+	else if (machine_is_msm7627a_qrd3()) {
+		sku3_lcdc_lcd_camera_power_init();
+		platform_add_devices(qrd3_fb_devices,
+						ARRAY_SIZE(qrd3_fb_devices));
+	} else
 		platform_add_devices(msm_fb_devices,
 				ARRAY_SIZE(msm_fb_devices));
 
 	msm_fb_register_device("mdp", &mdp_pdata);
 	if (machine_is_msm7625a_surf() || machine_is_msm7x27a_surf() ||
-			machine_is_msm8625_surf())
+			machine_is_msm8625_surf() || machine_is_msm7627a_qrd3())
 		msm_fb_register_device("lcdc", &lcdc_pdata);
-#ifdef CONFIG_FB_MSM_MDP303
+#ifdef CONFIG_FB_MSM_MIPI_DSI
 	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
 #endif
 }
diff --git a/arch/arm/mach-msm/board-msm7x27a-regulator.c b/arch/arm/mach-msm/board-msm7x27a-regulator.c
index 5be382f..469c543 100644
--- a/arch/arm/mach-msm/board-msm7x27a-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x27a-regulator.c
@@ -85,6 +85,7 @@
 	REGULATOR_SUPPLY("smps3",	NULL),
 	REGULATOR_SUPPLY("msme1",	NULL),
 	REGULATOR_SUPPLY("vcc_i2c",	"1-004a"),
+	REGULATOR_SUPPLY("vcc_i2c",	"1-0038"),
 };
 
 PCOM_VREG_CONSUMERS(smps4) = {
@@ -160,6 +161,7 @@
 	REGULATOR_SUPPLY("ldo12",	NULL),
 	REGULATOR_SUPPLY("gp2",		NULL),
 	REGULATOR_SUPPLY("vdd_ana",	"1-004a"),
+	REGULATOR_SUPPLY("vdd",		"1-0038"),
 };
 
 PCOM_VREG_CONSUMERS(ldo13) = {
@@ -215,7 +217,7 @@
 	PCOM_VREG_SMP(smps2,  4, NULL, 1100000, 1100000, 0, -1, 0, 0, 0, 0, s),
 	PCOM_VREG_SMP(smps3,  2, NULL, 1800000, 1800000, 0, -1, 0, 0, 0, 0, s),
 	PCOM_VREG_SMP(smps4, 24, NULL, 2100000, 2100000, 0, -1, 0, 0, 0, 0, s),
-	PCOM_VREG_LDO(ldo01, 12, NULL, 2100000, 2100000, 0, -1, 0, 0, 0, 0, p),
+	PCOM_VREG_LDO(ldo01, 12, NULL, 1800000, 2100000, 0, -1, 0, 0, 0, 0, p),
 	PCOM_VREG_LDO(ldo02, 13, NULL, 2850000, 2850000, 0, -1, 0, 0, 0, 0, p),
 	PCOM_VREG_LDO(ldo03, 49, NULL, 1200000, 1200000, 0, -1, 0, 0, 0, 0, n),
 	PCOM_VREG_LDO(ldo04, 50, NULL, 1100000, 1100000, 0, -1, 0, 0, 0, 0, n),
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index a6be53b..70efcce 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2704,7 +2704,7 @@
 #define MSM_ION_MM_SIZE		0x3600000 /* (54MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
 #define MSM_ION_WB_SIZE		0x600000 /* 6MB */
-#define MSM_ION_QSECOM_SIZE	0x300000 /* (3MB) */
+#define MSM_ION_QSECOM_SIZE	0x600000 /* (6MB) */
 #define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 41c02ab..3c01115 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -29,6 +29,7 @@
 #include <linux/i2c/atmel_mxt_ts.h>
 #include <linux/regulator/consumer.h>
 #include <linux/memblock.h>
+#include <linux/input/ft5x06_ts.h>
 #include <asm/mach/mmc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -126,7 +127,7 @@
 
 #ifdef CONFIG_ARCH_MSM7X27A
 #define MSM_PMEM_MDP_SIZE       0x1DD1000
-#define MSM_PMEM_ADSP_SIZE      0x1000000
+#define MSM_PMEM_ADSP_SIZE      0x1100000
 #endif
 
 #if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C) || \
@@ -258,6 +259,89 @@
 }
 #endif
 
+#define FT5X06_IRQ_GPIO		48
+#define FT5X06_RESET_GPIO	26
+
+static ssize_t
+ft5x06_virtual_keys_register(struct kobject *kobj,
+			     struct kobj_attribute *attr,
+			     char *buf)
+{
+	return snprintf(buf, 200,
+	__stringify(EV_KEY) ":" __stringify(KEY_MENU)  ":40:510:80:60"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME)   ":120:510:80:60"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":200:510:80:60"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_BACK)   ":280:510:80:60"
+	"\n");
+}
+
+static struct kobj_attribute ft5x06_virtual_keys_attr = {
+	.attr = {
+		.name = "virtualkeys.ft5x06_ts",
+		.mode = S_IRUGO,
+	},
+	.show = &ft5x06_virtual_keys_register,
+};
+
+static struct attribute *ft5x06_virtual_key_properties_attrs[] = {
+	&ft5x06_virtual_keys_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ft5x06_virtual_key_properties_attr_group = {
+	.attrs = ft5x06_virtual_key_properties_attrs,
+};
+
+struct kobject *ft5x06_virtual_key_properties_kobj;
+
+static struct ft5x06_ts_platform_data ft5x06_platformdata = {
+	.x_max		= 320,
+	.y_max		= 480,
+	.reset_gpio	= FT5X06_RESET_GPIO,
+	.irq_gpio	= FT5X06_IRQ_GPIO,
+	.irqflags	= IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+};
+
+static struct i2c_board_info ft5x06_device_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("ft5x06_ts", 0x38),
+		.platform_data = &ft5x06_platformdata,
+		.irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO),
+	},
+};
+
+static void ft5x06_touchpad_setup(void)
+{
+	int rc;
+
+	rc = gpio_tlmm_config(GPIO_CFG(FT5X06_IRQ_GPIO, 0,
+			GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
+			GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+	if (rc)
+		pr_err("%s: gpio_tlmm_config for %d failed\n",
+			__func__, FT5X06_IRQ_GPIO);
+
+	rc = gpio_tlmm_config(GPIO_CFG(FT5X06_RESET_GPIO, 0,
+			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+			GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+	if (rc)
+		pr_err("%s: gpio_tlmm_config for %d failed\n",
+			__func__, FT5X06_RESET_GPIO);
+
+	ft5x06_virtual_key_properties_kobj =
+			kobject_create_and_add("board_properties", NULL);
+
+	if (ft5x06_virtual_key_properties_kobj)
+		rc = sysfs_create_group(ft5x06_virtual_key_properties_kobj,
+				&ft5x06_virtual_key_properties_attr_group);
+
+	if (!ft5x06_virtual_key_properties_kobj || rc)
+		pr_err("%s: failed to create board_properties\n", __func__);
+
+	i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+				ft5x06_device_info,
+				ARRAY_SIZE(ft5x06_device_info));
+}
 
 static struct android_usb_platform_data android_usb_pdata = {
 	.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
@@ -1096,6 +1180,8 @@
 		i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
 					mxt_device_info,
 					ARRAY_SIZE(mxt_device_info));
+	} else if (machine_is_msm7627a_qrd3()) {
+		ft5x06_touchpad_setup();
 	}
 
 	/* headset */
@@ -1146,16 +1232,20 @@
 
 static void add_platform_devices(void)
 {
-	if (machine_is_msm8625_evb())
+	if (machine_is_msm8625_evb() || machine_is_msm8625_qrd7()) {
 		platform_add_devices(msm8625_evb_devices,
 				ARRAY_SIZE(msm8625_evb_devices));
-	else {
+		platform_add_devices(qrd3_devices,
+				ARRAY_SIZE(qrd3_devices));
+	} else {
 		platform_add_devices(qrd7627a_devices,
 				ARRAY_SIZE(qrd7627a_devices));
-		if (machine_is_msm7627a_qrd3())
-			platform_add_devices(qrd3_devices,
-					ARRAY_SIZE(qrd3_devices));
 	}
+
+	if (machine_is_msm7627a_qrd3())
+		platform_add_devices(qrd3_devices,
+			ARRAY_SIZE(qrd3_devices));
+
 	platform_add_devices(common_devices,
 			ARRAY_SIZE(common_devices));
 }
@@ -1188,6 +1278,23 @@
 	}
 }
 
+static void __init msm_pm_init(void)
+{
+	if (machine_is_msm8625_qrd7())
+		return;
+
+	if (!machine_is_msm8625_evb()) {
+		msm_pm_set_platform_data(msm7627a_pm_data,
+				ARRAY_SIZE(msm7627a_pm_data));
+		BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	} else {
+		msm_pm_set_platform_data(msm8625_pm_data,
+				ARRAY_SIZE(msm8625_pm_data));
+		BUG_ON(msm_pm_boot_init(&msm_pm_8625_boot_pdata));
+		msm8x25_spm_device_init();
+	}
+}
+
 static void __init msm_qrd_init(void)
 {
 	msm7x2x_misc_init();
@@ -1214,16 +1321,7 @@
 #ifdef CONFIG_USB_EHCI_MSM_72K
 	msm7627a_init_host();
 #endif
-	if (!machine_is_msm8625_evb()) {
-		msm_pm_set_platform_data(msm7627a_pm_data,
-				ARRAY_SIZE(msm7627a_pm_data));
-		BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
-	} else {
-		msm_pm_set_platform_data(msm8625_pm_data,
-				ARRAY_SIZE(msm8625_pm_data));
-		BUG_ON(msm_pm_boot_init(&msm_pm_8625_boot_pdata));
-		msm8x25_spm_device_init();
-	}
+	msm_pm_init();
 
 	msm_fb_add_devices();
 
@@ -1281,3 +1379,13 @@
 	.init_early	= qrd7627a_init_early,
 	.handle_irq	= gic_handle_irq,
 MACHINE_END
+MACHINE_START(MSM8625_QRD7, "QRD MSM8625 QRD7")
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= msm8625_map_io,
+	.reserve	= msm7627a_reserve,
+	.init_irq	= msm8625_init_irq,
+	.init_machine	= msm_qrd_init,
+	.timer		= &msm_timer,
+	.init_early	= qrd7627a_init_early,
+	.handle_irq	= gic_handle_irq,
+MACHINE_END
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 119f89c..3421bc1 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -811,8 +811,8 @@
 	},
 };
 
-/* For 8064, gfx3d_axi_clk is set as a dependency of gmem_axi_clk at runtime */
-static struct branch_clk gfx3d_axi_clk = {
+/* gfx3d_axi_clk is set as a dependency of gmem_axi_clk at runtime */
+static struct branch_clk gfx3d_axi_clk_8064 = {
 	.b = {
 		.ctl_reg = MAXI_EN5_REG,
 		.en_mask = BIT(25),
@@ -824,7 +824,23 @@
 	.c = {
 		.dbg_name = "gfx3d_axi_clk",
 		.ops = &clk_ops_branch,
-		CLK_INIT(gfx3d_axi_clk.c),
+		CLK_INIT(gfx3d_axi_clk_8064.c),
+	},
+};
+
+static struct branch_clk gfx3d_axi_clk_8930 = {
+	.b = {
+		.ctl_reg = MAXI_EN5_REG,
+		.en_mask = BIT(12),
+		.reset_reg = SW_RESET_AXI_REG,
+		.reset_mask = BIT(16),
+		.halt_reg = DBG_BUS_VEC_J_REG,
+		.halt_bit = 12,
+	},
+	.c = {
+		.dbg_name = "gfx3d_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gfx3d_axi_clk_8930.c),
 	},
 };
 
@@ -3322,12 +3338,40 @@
 	F_END
 };
 
+static struct clk_freq_tbl clk_tbl_gfx3d_8930[] = {
+	F_GFX3D(        0, gnd,   0,  0),
+	F_GFX3D( 27000000, pxo,   0,  0),
+	F_GFX3D( 48000000, pll8,  1,  8),
+	F_GFX3D( 54857000, pll8,  1,  7),
+	F_GFX3D( 64000000, pll8,  1,  6),
+	F_GFX3D( 76800000, pll8,  1,  5),
+	F_GFX3D( 96000000, pll8,  1,  4),
+	F_GFX3D(128000000, pll8,  1,  3),
+	F_GFX3D(145455000, pll2,  2, 11),
+	F_GFX3D(160000000, pll2,  1,  5),
+	F_GFX3D(177778000, pll2,  2,  9),
+	F_GFX3D(200000000, pll2,  1,  4),
+	F_GFX3D(228571000, pll2,  2,  7),
+	F_GFX3D(266667000, pll2,  1,  3),
+	F_GFX3D(300000000, pll3,  1,  4),
+	F_GFX3D(320000000, pll2,  2,  5),
+	F_GFX3D(400000000, pll2,  1,  2),
+	F_GFX3D(450000000, pll15, 1,  2),
+	F_END
+};
+
 static unsigned long fmax_gfx3d_8064[MAX_VDD_LEVELS] __initdata = {
 	[VDD_DIG_LOW]     = 128000000,
 	[VDD_DIG_NOMINAL] = 325000000,
 	[VDD_DIG_HIGH]    = 400000000
 };
 
+static unsigned long fmax_gfx3d_8930[MAX_VDD_LEVELS] __initdata = {
+	[VDD_DIG_LOW]     = 128000000,
+	[VDD_DIG_NOMINAL] = 320000000,
+	[VDD_DIG_HIGH]    = 450000000
+};
+
 static struct bank_masks bmnd_info_gfx3d = {
 	.bank_sel_mask =		BIT(11),
 	.bank0_mask = {
@@ -4649,10 +4693,11 @@
 	{ TEST_MM_HS(0x32), &csi_rdi2_clk.c },
 	{ TEST_MM_HS(0x33), &vcap_clk.c },
 	{ TEST_MM_HS(0x34), &vcap_npl_clk.c },
+	{ TEST_MM_HS(0x34), &gfx3d_axi_clk_8930.c },
 	{ TEST_MM_HS(0x35), &vcap_axi_clk.c },
 	{ TEST_MM_HS(0x36), &rgb_tv_clk.c },
 	{ TEST_MM_HS(0x37), &npl_tv_clk.c },
-	{ TEST_MM_HS(0x38), &gfx3d_axi_clk.c },
+	{ TEST_MM_HS(0x38), &gfx3d_axi_clk_8064.c },
 
 	{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
 	{ TEST_LPA(0x10), &codec_i2s_mic_bit_clk.c },
@@ -4865,6 +4910,7 @@
 	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.2"),
 	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_gss"),
 	CLK_LOOKUP("xo",		cxo_clk.c,	"BAM_RMNT"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"msm_xo"),
 	CLK_LOOKUP("pll2",		pll2_clk.c,	NULL),
 	CLK_LOOKUP("pll8",		pll8_clk.c,	NULL),
 	CLK_LOOKUP("pll4",		pll4_clk.c,	NULL),
@@ -4994,7 +5040,8 @@
 
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"footswitch-8x60.2"),
-	CLK_LOOKUP("bus_clk",		gfx3d_axi_clk.c, "footswitch-8x60.2"),
+	CLK_LOOKUP("bus_clk",
+			    gfx3d_axi_clk_8064.c, "footswitch-8x60.2"),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,           ""),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,	"footswitch-8x60.10"),
 	CLK_LOOKUP("bus_clk",		vcap_axi_clk.c,	"footswitch-8x60.10"),
@@ -5082,6 +5129,7 @@
 	CLK_LOOKUP("osr_clk",		spare_i2s_spkr_osr_clk.c,
 			   "msm-dai-q6.4"),
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		"msm-dai-q6.2"),
+	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		"msm-dai-q6.3"),
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	""),
 	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
 	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	""),
@@ -5093,7 +5141,7 @@
 	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		""),
 	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	""),
 	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8064.c,	""),
 
 	CLK_LOOKUP("dfab_dsps_clk",	dfab_dsps_clk.c, NULL),
 	CLK_LOOKUP("core_clk",		dfab_usb_hs_clk.c,	"msm_otg"),
@@ -5124,8 +5172,8 @@
 	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
 	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
 	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.9"),
-	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.10"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8064.c,	"msm_iommu.9"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8064.c,	"msm_iommu.10"),
 	CLK_LOOKUP("core_clk",		vcap_axi_clk.c,		"msm_iommu.11"),
 
 	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
@@ -5147,6 +5195,7 @@
 	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.1"),
 	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.2"),
 	CLK_LOOKUP("xo",		cxo_clk.c,	"BAM_RMNT"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"msm_xo"),
 	CLK_LOOKUP("pll2",		pll2_clk.c,	NULL),
 	CLK_LOOKUP("pll8",		pll8_clk.c,	NULL),
 	CLK_LOOKUP("pll4",		pll4_clk.c,	NULL),
@@ -5195,7 +5244,7 @@
 	CLK_LOOKUP("core_clk",		gsbi6_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi7_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi8_qup_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gsbi9_qup_clk.c,	"qup_i2c.0"),
+	CLK_LOOKUP("core_clk",		gsbi9_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi10_qup_clk.c,	"qup_i2c.10"),
 	CLK_LOOKUP("core_clk",		gsbi11_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi12_qup_clk.c,	"qup_i2c.12"),
@@ -5236,7 +5285,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,  "msm_serial_hs.0"),
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		gsbi8_p_clk.c,		""),
-	CLK_LOOKUP("iface_clk",		gsbi9_p_clk.c,		"qup_i2c.0"),
+	CLK_LOOKUP("iface_clk",		gsbi9_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		gsbi10_p_clk.c,		"qup_i2c.10"),
 	CLK_LOOKUP("iface_clk",		gsbi11_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		gsbi12_p_clk.c,		"qup_i2c.12"),
@@ -5385,6 +5434,7 @@
 	CLK_LOOKUP("osr_clk",		spare_i2s_spkr_osr_clk.c,
 			   "msm-dai-q6.4"),
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		"msm-dai-q6.2"),
+	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		"msm-dai-q6.3"),
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
 	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	"msm_iommu.0"),
@@ -5429,6 +5479,276 @@
 	CLK_LOOKUP("q6_func_clk",	q6_func_clk,  ""),
 };
 
+static struct clk_lookup msm_clocks_8930[] = {
+	CLK_LOOKUP("xo",		cxo_clk.c,	"msm_otg"),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	"pil_riva"),
+	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_qdsp6v4.0"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.1"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.2"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"BAM_RMNT"),
+	CLK_LOOKUP("pll2",		pll2_clk.c,	NULL),
+	CLK_LOOKUP("pll8",		pll8_clk.c,	NULL),
+	CLK_LOOKUP("pll4",		pll4_clk.c,	NULL),
+	CLK_LOOKUP("measure",		measure_clk.c,	"debug"),
+
+	CLK_LOOKUP("bus_clk",		afab_clk.c,		"msm_apps_fab"),
+	CLK_LOOKUP("bus_a_clk",		afab_a_clk.c,		"msm_apps_fab"),
+	CLK_LOOKUP("bus_clk",		cfpb_clk.c,		"msm_cpss_fpb"),
+	CLK_LOOKUP("bus_a_clk",		cfpb_a_clk.c,		"msm_cpss_fpb"),
+	CLK_LOOKUP("bus_clk",		sfab_clk.c,		"msm_sys_fab"),
+	CLK_LOOKUP("bus_a_clk",		sfab_msmbus_a_clk.c,	"msm_sys_fab"),
+	CLK_LOOKUP("bus_clk",		sfpb_clk.c,		"msm_sys_fpb"),
+	CLK_LOOKUP("bus_a_clk",		sfpb_a_clk.c,		"msm_sys_fpb"),
+	CLK_LOOKUP("bus_clk",		mmfab_clk.c,		"msm_mm_fab"),
+	CLK_LOOKUP("bus_a_clk",		mmfab_a_clk.c,		"msm_mm_fab"),
+	CLK_LOOKUP("mem_clk",		ebi1_msmbus_clk.c,	"msm_bus"),
+	CLK_LOOKUP("mem_a_clk",		ebi1_a_clk.c,		"msm_bus"),
+
+	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		NULL),
+	CLK_LOOKUP("dfab_clk",		dfab_clk.c,		NULL),
+	CLK_LOOKUP("dfab_a_clk",	dfab_a_clk.c,		NULL),
+	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		NULL),
+	CLK_LOOKUP("mmfpb_a_clk",	mmfpb_a_clk.c,		"clock-8960"),
+	CLK_LOOKUP("cfpb_a_clk",	cfpb_a_clk.c,		"clock-8960"),
+
+	CLK_LOOKUP("core_clk",		gp0_clk.c,		""),
+	CLK_LOOKUP("core_clk",		gp1_clk.c,		""),
+	CLK_LOOKUP("core_clk",		gp2_clk.c,		""),
+	CLK_LOOKUP("core_clk",		gsbi1_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi3_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi5_uart_clk.c, "msm_serial_hsl.0"),
+	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c, "msm_serial_hs.0"),
+	CLK_LOOKUP("core_clk",		gsbi7_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi8_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi9_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi10_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi11_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi12_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi1_qup_clk.c,	"spi_qsd.0"),
+	CLK_LOOKUP("core_clk",		gsbi2_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi3_qup_clk.c,	"qup_i2c.3"),
+	CLK_LOOKUP("core_clk",		gsbi4_qup_clk.c,	"qup_i2c.4"),
+	CLK_LOOKUP("core_clk",		gsbi5_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi6_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi7_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi8_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi9_qup_clk.c,	"qup_i2c.0"),
+	CLK_LOOKUP("core_clk",		gsbi10_qup_clk.c,	"qup_i2c.10"),
+	CLK_LOOKUP("core_clk",		gsbi11_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi12_qup_clk.c,	"qup_i2c.12"),
+	CLK_LOOKUP("core_clk",		pdm_clk.c,		""),
+	CLK_LOOKUP("mem_clk",		pmem_clk.c,		"msm_sps"),
+	CLK_LOOKUP("core_clk",		prng_clk.c,		"msm_rng.0"),
+	CLK_LOOKUP("core_clk",		sdc1_clk.c,		"msm_sdcc.1"),
+	CLK_LOOKUP("core_clk",		sdc2_clk.c,		"msm_sdcc.2"),
+	CLK_LOOKUP("core_clk",		sdc3_clk.c,		"msm_sdcc.3"),
+	CLK_LOOKUP("core_clk",		sdc4_clk.c,		"msm_sdcc.4"),
+	CLK_LOOKUP("core_clk",		sdc5_clk.c,		"msm_sdcc.5"),
+	CLK_LOOKUP("ref_clk",		tsif_ref_clk.c,		""),
+	CLK_LOOKUP("core_clk",		tssc_clk.c,		""),
+	CLK_LOOKUP("alt_core_clk",	usb_hs1_xcvr_clk.c,	"msm_otg"),
+	CLK_LOOKUP("phy_clk",		usb_phy0_clk.c,		"msm_otg"),
+	CLK_LOOKUP("alt_core_clk",	usb_fs1_xcvr_clk.c,	""),
+	CLK_LOOKUP("sys_clk",		usb_fs1_sys_clk.c,	""),
+	CLK_LOOKUP("src_clk",		usb_fs1_src_clk.c,	""),
+	CLK_LOOKUP("alt_core_clk",	usb_fs2_xcvr_clk.c,	""),
+	CLK_LOOKUP("sys_clk",		usb_fs2_sys_clk.c,	""),
+	CLK_LOOKUP("src_clk",		usb_fs2_src_clk.c,	""),
+	CLK_LOOKUP("alt_core_clk",    usb_hsic_xcvr_fs_clk.c,  "msm_hsic_host"),
+	CLK_LOOKUP("phy_clk",	      usb_hsic_hsic_clk.c,     "msm_hsic_host"),
+	CLK_LOOKUP("cal_clk",	      usb_hsic_hsio_cal_clk.c, "msm_hsic_host"),
+	CLK_LOOKUP("core_clk",	      usb_hsic_system_clk.c,   "msm_hsic_host"),
+	CLK_LOOKUP("iface_clk",	      usb_hsic_p_clk.c,        "msm_hsic_host"),
+	CLK_LOOKUP("iface_clk",		ce1_p_clk.c,		"qce.0"),
+	CLK_LOOKUP("iface_clk",		ce1_p_clk.c,		"qcrypto.0"),
+	CLK_LOOKUP("core_clk",		ce1_core_clk.c,		"qce.0"),
+	CLK_LOOKUP("core_clk",		ce1_core_clk.c,		"qcrypto.0"),
+	CLK_LOOKUP("dma_bam_pclk",	dma_bam_p_clk.c,	NULL),
+	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,		"spi_qsd.0"),
+	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi3_p_clk.c,		"qup_i2c.3"),
+	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,		"qup_i2c.4"),
+	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,	"msm_serial_hsl.0"),
+	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,  "msm_serial_hs.0"),
+	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi8_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi9_p_clk.c,		"qup_i2c.0"),
+	CLK_LOOKUP("iface_clk",		gsbi10_p_clk.c,		"qup_i2c.10"),
+	CLK_LOOKUP("iface_clk",		gsbi11_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi12_p_clk.c,		"qup_i2c.12"),
+	CLK_LOOKUP("iface_clk",		tsif_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		usb_fs1_p_clk.c,	""),
+	CLK_LOOKUP("iface_clk",		usb_fs2_p_clk.c,	""),
+	CLK_LOOKUP("iface_clk",		usb_hs1_p_clk.c,	"msm_otg"),
+	CLK_LOOKUP("iface_clk",		sdc1_p_clk.c,		"msm_sdcc.1"),
+	CLK_LOOKUP("iface_clk",		sdc2_p_clk.c,		"msm_sdcc.2"),
+	CLK_LOOKUP("iface_clk",		sdc3_p_clk.c,		"msm_sdcc.3"),
+	CLK_LOOKUP("iface_clk",		sdc4_p_clk.c,		"msm_sdcc.4"),
+	CLK_LOOKUP("iface_clk",		sdc5_p_clk.c,		"msm_sdcc.5"),
+	CLK_LOOKUP("core_clk",		adm0_clk.c,		"msm_dmov"),
+	CLK_LOOKUP("iface_clk",		adm0_p_clk.c,		"msm_dmov"),
+	CLK_LOOKUP("iface_clk",		pmic_arb0_p_clk.c,	""),
+	CLK_LOOKUP("iface_clk",		pmic_arb1_p_clk.c,	""),
+	CLK_LOOKUP("core_clk",		pmic_ssbi2_clk.c,	""),
+	CLK_LOOKUP("mem_clk",		rpm_msg_ram_p_clk.c,	""),
+	CLK_LOOKUP("core_clk",		amp_clk.c,		""),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-001a"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-006c"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0048"),
+	CLK_LOOKUP("cam_clk",		cam2_clk.c,		NULL),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0020"),
+	CLK_LOOKUP("csi_src_clk",	csi0_src_clk.c,		"msm_csid.0"),
+	CLK_LOOKUP("csi_src_clk",	csi1_src_clk.c,		"msm_csid.1"),
+	CLK_LOOKUP("csi_src_clk",	csi2_src_clk.c,		"msm_csid.2"),
+	CLK_LOOKUP("csi_clk",		csi0_clk.c,		"msm_csid.0"),
+	CLK_LOOKUP("csi_clk",		csi1_clk.c,		"msm_csid.1"),
+	CLK_LOOKUP("csi_clk",		csi2_clk.c,		"msm_csid.2"),
+	CLK_LOOKUP("csi_phy_clk",	csi0_phy_clk.c,		"msm_csid.0"),
+	CLK_LOOKUP("csi_phy_clk",	csi1_phy_clk.c,		"msm_csid.1"),
+	CLK_LOOKUP("csi_phy_clk",	csi2_phy_clk.c,		"msm_csid.2"),
+	CLK_LOOKUP("csi_pix_clk",	csi_pix_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_rdi_clk",	csi_rdi_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_src_clk",	csi2_src_clk.c,		NULL),
+	CLK_LOOKUP("csi_clk",		csi2_clk.c,		NULL),
+	CLK_LOOKUP("csi_pix1_clk",	csi_pix1_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_rdi1_clk",	csi_rdi1_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_rdi2_clk",	csi_rdi2_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_phy_clk",	csi2_phy_clk.c,		NULL),
+	CLK_LOOKUP("csi2phy_timer_clk",	csi2phy_timer_clk.c,	NULL),
+	CLK_LOOKUP("csiphy_timer_src_clk",
+			   csiphy_timer_src_clk.c, "msm_csiphy.0"),
+	CLK_LOOKUP("csiphy_timer_src_clk",
+			   csiphy_timer_src_clk.c, "msm_csiphy.1"),
+	CLK_LOOKUP("csiphy_timer_src_clk",
+			   csiphy_timer_src_clk.c, "msm_csiphy.2"),
+	CLK_LOOKUP("csiphy_timer_clk",	csi0phy_timer_clk.c,	"msm_csiphy.0"),
+	CLK_LOOKUP("csiphy_timer_clk",	csi1phy_timer_clk.c,	"msm_csiphy.1"),
+	CLK_LOOKUP("csiphy_timer_clk",	csi2phy_timer_clk.c,	"msm_csiphy.2"),
+	CLK_LOOKUP("dsi_byte_div_clk",	dsi1_byte_clk.c,	NULL),
+	CLK_LOOKUP("dsi_esc_clk",	dsi1_esc_clk.c,		NULL),
+	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"kgsl-3d0.0"),
+	CLK_LOOKUP("core_clk",		gfx3d_clk.c,	"footswitch-8x60.2"),
+	CLK_LOOKUP("bus_clk",
+			    gfx3d_axi_clk_8930.c, "footswitch-8x60.2"),
+	CLK_LOOKUP("bus_clk",		ijpeg_axi_clk.c, "footswitch-8x60.3"),
+	CLK_LOOKUP("imem_clk",		imem_axi_clk.c,		NULL),
+	CLK_LOOKUP("ijpeg_clk",         ijpeg_clk.c,            NULL),
+	CLK_LOOKUP("core_clk",		ijpeg_clk.c,	"footswitch-8x60.3"),
+	CLK_LOOKUP("mdp_clk",		mdp_clk.c,		NULL),
+	CLK_LOOKUP("core_clk",		mdp_clk.c,	"footswitch-8x60.4"),
+	CLK_LOOKUP("mdp_vsync_clk",	mdp_vsync_clk.c,	NULL),
+	CLK_LOOKUP("vsync_clk",		mdp_vsync_clk.c, "footswitch-8x60.4"),
+	CLK_LOOKUP("lut_mdp",		lut_mdp_clk.c,		NULL),
+	CLK_LOOKUP("lut_clk",		lut_mdp_clk.c,	"footswitch-8x60.4"),
+	CLK_LOOKUP("core_clk",		rot_clk.c,	"msm_rotator.0"),
+	CLK_LOOKUP("core_clk",		rot_clk.c,	"footswitch-8x60.6"),
+	CLK_LOOKUP("tv_src_clk",	tv_src_clk.c,		NULL),
+	CLK_LOOKUP("tv_src_clk",	tv_src_clk.c,	"footswitch-8x60.4"),
+	CLK_LOOKUP("tv_dac_clk",	tv_dac_clk.c,		NULL),
+	CLK_LOOKUP("core_clk",		vcodec_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("core_clk",		vcodec_clk.c,	"footswitch-8x60.7"),
+	CLK_LOOKUP("mdp_tv_clk",	mdp_tv_clk.c,		NULL),
+	CLK_LOOKUP("tv_clk",		mdp_tv_clk.c,	"footswitch-8x60.4"),
+	CLK_LOOKUP("hdmi_clk",		hdmi_tv_clk.c,		NULL),
+	CLK_LOOKUP("core_clk",		hdmi_app_clk.c,	"hdmi_msm.1"),
+	CLK_LOOKUP("vpe_clk",		vpe_clk.c,		"msm_vpe.0"),
+	CLK_LOOKUP("core_clk",		vpe_clk.c,	"footswitch-8x60.9"),
+	CLK_LOOKUP("vfe_clk",		vfe_clk.c,		"msm_vfe.0"),
+	CLK_LOOKUP("core_clk",		vfe_clk.c,	"footswitch-8x60.8"),
+	CLK_LOOKUP("csi_vfe_clk",	csi_vfe_clk.c,		"msm_vfe.0"),
+	CLK_LOOKUP("bus_clk",		vfe_axi_clk.c,	"footswitch-8x60.8"),
+	CLK_LOOKUP("bus_clk",		mdp_axi_clk.c,	"footswitch-8x60.4"),
+	CLK_LOOKUP("bus_clk",		rot_axi_clk.c,	"footswitch-8x60.6"),
+	CLK_LOOKUP("bus_clk",		vcodec_axi_clk.c, "footswitch-8x60.7"),
+	CLK_LOOKUP("bus_a_clk",	       vcodec_axi_a_clk.c, "footswitch-8x60.7"),
+	CLK_LOOKUP("bus_b_clk",        vcodec_axi_b_clk.c, "footswitch-8x60.7"),
+	CLK_LOOKUP("bus_clk",		vpe_axi_clk.c,	"footswitch-8x60.9"),
+	CLK_LOOKUP("amp_pclk",		amp_p_clk.c,		NULL),
+	CLK_LOOKUP("csi_pclk",		csi_p_clk.c,		"msm_csid.0"),
+	CLK_LOOKUP("csi_pclk",		csi_p_clk.c,		"msm_csid.1"),
+	CLK_LOOKUP("csi_pclk",		csi_p_clk.c,		"msm_csid.2"),
+	CLK_LOOKUP("dsi_m_pclk",	dsi1_m_p_clk.c,		NULL),
+	CLK_LOOKUP("dsi_s_pclk",	dsi1_s_p_clk.c,		NULL),
+	CLK_LOOKUP("iface_clk",		gfx3d_p_clk.c,	"kgsl-3d0.0"),
+	CLK_LOOKUP("iface_clk",		gfx3d_p_clk.c,	"footswitch-8x60.2"),
+	CLK_LOOKUP("master_iface_clk",	hdmi_m_p_clk.c,	"hdmi_msm.1"),
+	CLK_LOOKUP("slave_iface_clk",	hdmi_s_p_clk.c,	"hdmi_msm.1"),
+	CLK_LOOKUP("ijpeg_pclk",	ijpeg_p_clk.c,		NULL),
+	CLK_LOOKUP("iface_clk",		ijpeg_p_clk.c,	"footswitch-8x60.3"),
+	CLK_LOOKUP("mem_iface_clk",	imem_p_clk.c,	"kgsl-3d0.0"),
+	CLK_LOOKUP("mdp_pclk",		mdp_p_clk.c,		NULL),
+	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,	"footswitch-8x60.4"),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,	"msm_iommu"),
+	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"msm_rotator.0"),
+	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"footswitch-8x60.6"),
+	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,	"footswitch-8x60.7"),
+	CLK_LOOKUP("vfe_pclk",		vfe_p_clk.c,		"msm_vfe.0"),
+	CLK_LOOKUP("iface_clk",		vfe_p_clk.c,	"footswitch-8x60.8"),
+	CLK_LOOKUP("vpe_pclk",		vpe_p_clk.c,		"msm_vpe.0"),
+	CLK_LOOKUP("iface_clk",		vpe_p_clk.c,	"footswitch-8x60.9"),
+	CLK_LOOKUP("bit_clk",		mi2s_bit_clk.c,		"msm-dai-q6.6"),
+	CLK_LOOKUP("osr_clk",		mi2s_osr_clk.c,		"msm-dai-q6.6"),
+	CLK_LOOKUP("bit_clk",		codec_i2s_mic_bit_clk.c,
+			   "msm-dai-q6.1"),
+	CLK_LOOKUP("osr_clk",		codec_i2s_mic_osr_clk.c,
+			   "msm-dai-q6.1"),
+	CLK_LOOKUP("bit_clk",		spare_i2s_mic_bit_clk.c,
+			   "msm-dai-q6.5"),
+	CLK_LOOKUP("osr_clk",		spare_i2s_mic_osr_clk.c,
+			   "msm-dai-q6.5"),
+	CLK_LOOKUP("bit_clk",		codec_i2s_spkr_bit_clk.c,
+			   "msm-dai-q6.16384"),
+	CLK_LOOKUP("osr_clk",		codec_i2s_spkr_osr_clk.c,
+			   "msm-dai-q6.16384"),
+	CLK_LOOKUP("bit_clk",		spare_i2s_spkr_bit_clk.c,
+			   "msm-dai-q6.4"),
+	CLK_LOOKUP("osr_clk",		spare_i2s_spkr_osr_clk.c,
+			   "msm-dai-q6.4"),
+	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		"msm-dai-q6.2"),
+	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	NULL),
+	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
+	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		"msm_iommu.1"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.2"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.3"),
+	CLK_LOOKUP("core_clk",		rot_axi_clk.c,		"msm_iommu.4"),
+	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,	"msm_iommu.5"),
+	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8930.c,	"msm_iommu.9"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk_8930.c,	"msm_iommu.10"),
+
+	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("vcodec_iommu0_clk", vcodec_axi_a_clk.c, "msm_vidc.0"),
+	CLK_LOOKUP("vcodec_iommu1_clk", vcodec_axi_b_clk.c, "msm_vidc.0"),
+	CLK_LOOKUP("smmu_iface_clk", smmu_p_clk.c,	"msm_vidc.0"),
+
+	CLK_LOOKUP("dfab_dsps_clk",	dfab_dsps_clk.c, NULL),
+	CLK_LOOKUP("core_clk",		dfab_usb_hs_clk.c,	"msm_otg"),
+	CLK_LOOKUP("bus_clk",		dfab_sdc1_clk.c, "msm_sdcc.1"),
+	CLK_LOOKUP("bus_clk",		dfab_sdc2_clk.c, "msm_sdcc.2"),
+	CLK_LOOKUP("bus_clk",		dfab_sdc3_clk.c, "msm_sdcc.3"),
+	CLK_LOOKUP("bus_clk",		dfab_sdc4_clk.c, "msm_sdcc.4"),
+	CLK_LOOKUP("bus_clk",		dfab_sdc5_clk.c, "msm_sdcc.5"),
+	CLK_LOOKUP("dfab_clk",		dfab_sps_clk.c,	"msm_sps"),
+	CLK_LOOKUP("bus_clk",		dfab_bam_dmux_clk.c,	"BAM_RMNT"),
+	CLK_LOOKUP("bus_clk",		dfab_scm_clk.c,	"scm"),
+	CLK_LOOKUP("bus_clk",		dfab_qseecom_clk.c,	"qseecom"),
+
+	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
+
+	CLK_LOOKUP("l2_mclk",		l2_m_clk,     ""),
+	CLK_LOOKUP("krait0_mclk",	krait0_m_clk, ""),
+	CLK_LOOKUP("krait1_mclk",	krait1_m_clk, ""),
+	CLK_LOOKUP("q6sw_clk",		q6sw_clk,     ""),
+	CLK_LOOKUP("q6fw_clk",		q6fw_clk,     ""),
+	CLK_LOOKUP("q6_func_clk",	q6_func_clk,  ""),
+};
 /*
  * Miscellaneous clock register initializations
  */
@@ -5472,8 +5792,8 @@
 	writel_relaxed(0, SW_RESET_ALL_REG);
 
 	/*
-	 * Some bits are only used on either 8960 or 8064 and are marked as
-	 * reserved bits on the other SoC. Writing to these reserved bits
+	 * Some bits are only used on 8960 or 8064 or 8930 and are marked as
+	 * reserved bits on the other SoCs. Writing to these reserved bits
 	 * should have no effect.
 	 */
 	/*
@@ -5513,6 +5833,8 @@
 	rmwreg(0x0027FCFF, MAXI_EN3_REG, 0x003FFFFF);
 	if (cpu_is_apq8064())
 		rmwreg(0x009FE4FF, MAXI_EN5_REG, 0x01FFEFFF);
+	if (cpu_is_msm8930())
+		rmwreg(0x000004FF, MAXI_EN5_REG, 0x00000FFF);
 	if (cpu_is_msm8960())
 		rmwreg(0x00003C38, SAXI_EN_REG,  0x00003FFF);
 	else
@@ -5531,12 +5853,9 @@
 	rmwreg(0x00000000, CSI0_CC_REG,       0x00000410);
 	rmwreg(0x00000000, CSI1_CC_REG,       0x00000410);
 	rmwreg(0x80FF0000, DSI1_BYTE_CC_REG,  0xE0FF0010);
-	rmwreg(0x80FF0000, DSI2_BYTE_CC_REG,  0xE0FF0010);
 	rmwreg(0x80FF0000, DSI_PIXEL_CC_REG,  0xE0FF0010);
-	rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
 	rmwreg(0xC0FF0000, GFX3D_CC_REG,      0xE0FF0010);
 	rmwreg(0x80FF0000, IJPEG_CC_REG,      0xE0FF0010);
-	rmwreg(0x80FF0000, JPEGD_CC_REG,      0xE0FF0010);
 	rmwreg(0x80FF0000, MDP_CC_REG,        0xE1FF0010);
 	rmwreg(0x80FF0000, MDP_LUT_CC_REG,    0xE0FF0010);
 	rmwreg(0x80FF0000, ROT_CC_REG,        0xE0FF0010);
@@ -5545,10 +5864,17 @@
 	rmwreg(0x80FF0000, VFE_CC_REG,        0xE0FF4010);
 	rmwreg(0x800000FF, VFE_CC2_REG,       0xE00000FF);
 	rmwreg(0x80FF0000, VPE_CC_REG,        0xE0FF0010);
-	if (cpu_is_msm8960() || cpu_is_msm8930()) {
+	if (cpu_is_msm8960() || cpu_is_apq8064()) {
+		rmwreg(0x80FF0000, DSI2_BYTE_CC_REG,  0xE0FF0010);
+		rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
+		rmwreg(0x80FF0000, JPEGD_CC_REG,      0xE0FF0010);
+	}
+	if (cpu_is_msm8960() || cpu_is_msm8930())
+		rmwreg(0x80FF0000, TV_CC_REG,         0xE1FFC010);
+
+	if (cpu_is_msm8960()) {
 		rmwreg(0x80FF0000, GFX2D0_CC_REG,     0xE0FF0010);
 		rmwreg(0x80FF0000, GFX2D1_CC_REG,     0xE0FF0010);
-		rmwreg(0x80FF0000, TV_CC_REG,         0xE1FFC010);
 	}
 	if (cpu_is_apq8064()) {
 		rmwreg(0x00000000, TV_CC_REG,         0x00004010);
@@ -5590,12 +5916,13 @@
 	writel_relaxed(BIT(15), PDM_CLK_NS_REG);
 
 	/* Source SLIMBus xo src from slimbus reference clock */
-	if (cpu_is_msm8960() || cpu_is_msm8930())
+	if (cpu_is_msm8960())
 		writel_relaxed(0x3, SLIMBUS_XO_SRC_CLK_CTL_REG);
 
 	/* Source the dsi_byte_clks from the DSI PHY PLLs */
 	rmwreg(0x1, DSI1_BYTE_NS_REG, 0x7);
-	rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
+	if (cpu_is_msm8960() || cpu_is_apq8064())
+		rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
 
 	/* Source the sata_phy_ref_clk from PXO */
 	if (cpu_is_apq8064())
@@ -5688,7 +6015,21 @@
 		memcpy(vfe_clk.c.fmax, fmax_vfe_8064,
 		       sizeof(vfe_clk.c.fmax));
 
-		gmem_axi_clk.c.depends = &gfx3d_axi_clk.c;
+		gmem_axi_clk.c.depends = &gfx3d_axi_clk_8064.c;
+	}
+
+	/*
+	 * Change the freq tables and voltage requirements for
+	 * clocks which differ between 8960 and 8930.
+	 */
+	if (cpu_is_msm8930()) {
+		gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8930;
+
+		memcpy(gfx3d_clk.c.fmax, fmax_gfx3d_8930,
+		       sizeof(gfx3d_clk.c.fmax));
+
+		pll15_clk.c.rate = 900000000;
+		gmem_axi_clk.c.depends = &gfx3d_axi_clk_8930.c;
 	}
 
 	vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
@@ -5788,3 +6129,10 @@
 	.init = msm8960_clock_init,
 	.late_init = msm8960_clock_late_init,
 };
+
+struct clock_init_data msm8930_clock_init_data __initdata = {
+	.table = msm_clocks_8930,
+	.size = ARRAY_SIZE(msm_clocks_8930),
+	.init = msm8960_clock_init,
+	.late_init = msm8960_clock_late_init,
+};
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 3e059b6..6f02b75 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1602,6 +1602,7 @@
 	CLK_LOOKUP("xo",	cxo_a_clk.c,	""),
 	CLK_LOOKUP("xo",	cxo_clk.c,	"msm_otg"),
 	CLK_LOOKUP("xo",	cxo_clk.c,	"BAM_RMNT"),
+	CLK_LOOKUP("xo",	cxo_clk.c,	"msm_xo"),
 	CLK_LOOKUP("pll0",	pll0_clk.c,	NULL),
 	CLK_LOOKUP("pll8",	pll8_clk.c,	NULL),
 	CLK_LOOKUP("pll14",	pll14_clk.c,	NULL),
@@ -1692,6 +1693,7 @@
 	CLK_LOOKUP("osr_clk",		spare_i2s_spkr_osr_clk.c,
 			   "msm-dai-q6.4"),
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,	"msm-dai-q6.2"),
+	CLK_LOOKUP("pcm_clk",		pcm_clk.c,	"msm-dai-q6.3"),
 
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index bce2e0f..785e838 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -149,6 +149,7 @@
 extern struct clock_init_data msm8x60_clock_init_data;
 extern struct clock_init_data qds8x50_clock_init_data;
 extern struct clock_init_data msm8625_dummy_clock_init_data;
+extern struct clock_init_data msm8930_clock_init_data;
 
 void msm_clock_init(struct clock_init_data *data);
 int vote_vdd_level(struct clk_vdd_class *vdd_class, int level);
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 3632d80..1e539b2 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -30,6 +30,7 @@
 #include <mach/rpm.h>
 #include <mach/mdm2.h>
 #include <mach/msm_smd.h>
+#include <mach/msm_dcvs.h>
 #include <linux/ion.h>
 #include "clock.h"
 #include "devices.h"
@@ -399,7 +400,7 @@
  * Machine specific data for AUX PCM Interface
  * which the driver will  be unware of.
  */
-struct msm_dai_auxpcm_pdata apq_auxpcm_rx_pdata = {
+struct msm_dai_auxpcm_pdata apq_auxpcm_pdata = {
 	.clk = "pcm_clk",
 	.mode = AFE_PCM_CFG_MODE_PCM,
 	.sync = AFE_PCM_CFG_SYNC_INT,
@@ -414,13 +415,16 @@
 	.name = "msm-dai-q6",
 	.id = 2,
 	.dev = {
-		.platform_data = &apq_auxpcm_rx_pdata,
+		.platform_data = &apq_auxpcm_pdata,
 	},
 };
 
 struct platform_device apq_cpudai_auxpcm_tx = {
 	.name = "msm-dai-q6",
 	.id = 3,
+	.dev = {
+		.platform_data = &apq_auxpcm_pdata,
+	},
 };
 
 struct platform_device apq_cpu_fe = {
@@ -2139,3 +2143,50 @@
 	.num_resources	= ARRAY_SIZE(mdm_resources),
 	.resource	= mdm_resources,
 };
+
+static int apq8064_LPM_latency = 1000; /* >100 usec for WFI */
+
+struct platform_device apq8064_cpu_idle_device = {
+	.name   = "msm_cpu_idle",
+	.id     = -1,
+	.dev = {
+		.platform_data = &apq8064_LPM_latency,
+	},
+};
+
+static struct msm_dcvs_freq_entry apq8064_freq[] = {
+	{ 384000, 166981,  345600},
+	{ 702000, 213049,  632502},
+	{1026000, 285712,  925613},
+	{1242000, 383945, 1176550},
+	{1458000, 419729, 1465478},
+	{1512000, 434116, 1546674},
+
+};
+
+static struct msm_dcvs_core_info apq8064_core_info = {
+	.freq_tbl = &apq8064_freq[0],
+	.core_param = {
+		.max_time_us = 100000,
+		.num_freq = ARRAY_SIZE(apq8064_freq),
+	},
+	.algo_param = {
+		.slack_time_us = 58000,
+		.scale_slack_time = 0,
+		.scale_slack_time_pct = 0,
+		.disable_pc_threshold = 1458000,
+		.em_window_size = 100000,
+		.em_max_util_pct = 97,
+		.ss_window_size = 1000000,
+		.ss_util_pct = 95,
+		.ss_iobusy_conv = 100,
+	},
+};
+
+struct platform_device apq8064_msm_gov_device = {
+	.name = "msm_dcvs_gov",
+	.id = -1,
+	.dev = {
+		.platform_data = &apq8064_core_info,
+	},
+};
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index 81c52d1..da3574b 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -13,9 +13,15 @@
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/ion.h>
 #include <mach/msm_iomap.h>
 #include <mach/irqs-8930.h>
 #include <mach/rpm.h>
+#include <mach/msm_dcvs.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/socinfo.h>
 
 #include "devices.h"
 #include "rpm_log.h"
@@ -59,7 +65,7 @@
 				APPS_FABRIC_CFG_CLKMOD, 3),
 		MSM_RPM_MAP(8930, APPS_FABRIC_CFG_IOCTL,
 				APPS_FABRIC_CFG_IOCTL, 1),
-		MSM_RPM_MAP(8930, APPS_FABRIC_ARB_0, APPS_FABRIC_ARB, 12),
+		MSM_RPM_MAP(8930, APPS_FABRIC_ARB_0, APPS_FABRIC_ARB, 6),
 		MSM_RPM_MAP(8930, SYS_FABRIC_CFG_HALT_0,
 				SYS_FABRIC_CFG_HALT, 2),
 		MSM_RPM_MAP(8930, SYS_FABRIC_CFG_CLKMOD_0,
@@ -67,14 +73,14 @@
 		MSM_RPM_MAP(8930, SYS_FABRIC_CFG_IOCTL,
 				SYS_FABRIC_CFG_IOCTL, 1),
 		MSM_RPM_MAP(8930, SYSTEM_FABRIC_ARB_0,
-				SYSTEM_FABRIC_ARB, 29),
+				SYSTEM_FABRIC_ARB, 20),
 		MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_HALT_0,
 				MMSS_FABRIC_CFG_HALT, 2),
 		MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_CLKMOD_0,
 				MMSS_FABRIC_CFG_CLKMOD, 3),
 		MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_IOCTL,
 				MMSS_FABRIC_CFG_IOCTL, 1),
-		MSM_RPM_MAP(8930, MM_FABRIC_ARB_0, MM_FABRIC_ARB, 23),
+		MSM_RPM_MAP(8930, MM_FABRIC_ARB_0, MM_FABRIC_ARB, 11),
 		MSM_RPM_MAP(8930, PM8038_S1_0, PM8038_S1, 2),
 		MSM_RPM_MAP(8930, PM8038_S2_0, PM8038_S2, 2),
 		MSM_RPM_MAP(8930, PM8038_S3_0, PM8038_S3, 2),
@@ -275,3 +281,349 @@
 	},
 };
 
+static int msm8930_LPM_latency = 1000; /* >100 usec for WFI */
+
+struct platform_device msm8930_cpu_idle_device = {
+	.name   = "msm_cpu_idle",
+	.id     = -1,
+	.dev = {
+		.platform_data = &msm8930_LPM_latency,
+	},
+};
+
+static struct msm_dcvs_freq_entry msm8930_freq[] = {
+	{ 384000, 166981,  345600},
+	{ 702000, 213049,  632502},
+	{1026000, 285712,  925613},
+	{1242000, 383945, 1176550},
+	{1458000, 419729, 1465478},
+	{1512000, 434116, 1546674},
+
+};
+
+static struct msm_dcvs_core_info msm8930_core_info = {
+	.freq_tbl = &msm8930_freq[0],
+	.core_param = {
+		.max_time_us = 100000,
+		.num_freq = ARRAY_SIZE(msm8930_freq),
+	},
+	.algo_param = {
+		.slack_time_us = 58000,
+		.scale_slack_time = 0,
+		.scale_slack_time_pct = 0,
+		.disable_pc_threshold = 1458000,
+		.em_window_size = 100000,
+		.em_max_util_pct = 97,
+		.ss_window_size = 1000000,
+		.ss_util_pct = 95,
+		.ss_iobusy_conv = 100,
+	},
+};
+
+struct platform_device msm8930_msm_gov_device = {
+	.name = "msm_dcvs_gov",
+	.id = -1,
+	.dev = {
+		.platform_data = &msm8930_core_info,
+	},
+};
+
+struct platform_device msm_bus_8930_sys_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    =  MSM_BUS_FAB_SYSTEM,
+};
+struct platform_device msm_bus_8930_apps_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_APPSS,
+};
+struct platform_device msm_bus_8930_mm_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_MMSS,
+};
+struct platform_device msm_bus_8930_sys_fpb = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_SYSTEM_FPB,
+};
+struct platform_device msm_bus_8930_cpss_fpb = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_CPSS_FPB,
+};
+
+/* MSM Video core device */
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors vidc_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+static struct msm_bus_vectors vidc_venc_vga_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 54525952,
+		.ib  = 436207616,
+	},
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 72351744,
+		.ib  = 289406976,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 1000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 1000000,
+	},
+};
+static struct msm_bus_vectors vidc_vdec_vga_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 40894464,
+		.ib  = 327155712,
+	},
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 48234496,
+		.ib  = 192937984,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 2000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 2000000,
+	},
+};
+static struct msm_bus_vectors vidc_venc_720p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 163577856,
+		.ib  = 1308622848,
+	},
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 219152384,
+		.ib  = 876609536,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 3500000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 3500000,
+	},
+};
+static struct msm_bus_vectors vidc_vdec_720p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 121634816,
+		.ib  = 973078528,
+	},
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 155189248,
+		.ib  = 620756992,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 7000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 7000000,
+	},
+};
+static struct msm_bus_vectors vidc_venc_1080p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 372244480,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 501219328,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 5000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 5000000,
+	},
+};
+static struct msm_bus_vectors vidc_vdec_1080p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 222298112,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_HD_CODEC_PORT1,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 330301440,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 700000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 10000000,
+	},
+};
+
+static struct msm_bus_paths vidc_bus_client_config[] = {
+	{
+		ARRAY_SIZE(vidc_init_vectors),
+		vidc_init_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_venc_vga_vectors),
+		vidc_venc_vga_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_vdec_vga_vectors),
+		vidc_vdec_vga_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_venc_720p_vectors),
+		vidc_venc_720p_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_vdec_720p_vectors),
+		vidc_vdec_720p_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_venc_1080p_vectors),
+		vidc_venc_1080p_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_vdec_1080p_vectors),
+		vidc_vdec_1080p_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata vidc_bus_client_data = {
+	vidc_bus_client_config,
+	ARRAY_SIZE(vidc_bus_client_config),
+	.name = "vidc",
+};
+#endif
+
+#define MSM_VIDC_BASE_PHYS 0x04400000
+#define MSM_VIDC_BASE_SIZE 0x00100000
+
+static struct resource apq8930_device_vidc_resources[] = {
+	{
+		.start	= MSM_VIDC_BASE_PHYS,
+		.end	= MSM_VIDC_BASE_PHYS + MSM_VIDC_BASE_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= VCODEC_IRQ,
+		.end	= VCODEC_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct msm_vidc_platform_data apq8930_vidc_platform_data = {
+#ifdef CONFIG_MSM_BUS_SCALING
+	.vidc_bus_client_pdata = &vidc_bus_client_data,
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	.memtype = ION_CP_MM_HEAP_ID,
+	.enable_ion = 1,
+#else
+	.memtype = MEMTYPE_EBI1,
+	.enable_ion = 0,
+#endif
+	.disable_dmx = 0,
+	.disable_fullhd = 0,
+};
+
+struct platform_device apq8930_msm_device_vidc = {
+	.name = "msm_vidc",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(apq8930_device_vidc_resources),
+	.resource = apq8930_device_vidc_resources,
+	.dev = {
+		.platform_data = &apq8930_vidc_platform_data,
+	},
+};
+
+struct platform_device *vidc_device[] __initdata = {
+	&apq8930_msm_device_vidc
+};
+
+void __init msm8930_add_vidc_device(void)
+{
+	if (cpu_is_msm8627()) {
+		struct msm_vidc_platform_data *pdata;
+		pdata = (struct msm_vidc_platform_data *)
+			apq8930_msm_device_vidc.dev.platform_data;
+		pdata->disable_fullhd = 1;
+	}
+	platform_add_devices(vidc_device, ARRAY_SIZE(vidc_device));
+}
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index f4af677..42df652 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -43,6 +43,7 @@
 #include "rpm_stats.h"
 #include "pil-q6v4.h"
 #include "scm-pas.h"
+#include <mach/msm_dcvs.h>
 
 #ifdef CONFIG_MSM_MPM
 #include "mpm.h"
@@ -1786,7 +1787,7 @@
  * Machine specific data for AUX PCM Interface
  * which the driver will  be unware of.
  */
-struct msm_dai_auxpcm_pdata auxpcm_rx_pdata = {
+struct msm_dai_auxpcm_pdata auxpcm_pdata = {
 	.clk = "pcm_clk",
 	.mode = AFE_PCM_CFG_MODE_PCM,
 	.sync = AFE_PCM_CFG_SYNC_INT,
@@ -1801,13 +1802,16 @@
 	.name = "msm-dai-q6",
 	.id = 2,
 	.dev = {
-		.platform_data = &auxpcm_rx_pdata,
+		.platform_data = &auxpcm_pdata,
 	},
 };
 
 struct platform_device msm_cpudai_auxpcm_tx = {
 	.name = "msm-dai-q6",
 	.id = 3,
+	.dev = {
+		.platform_data = &auxpcm_pdata,
+	},
 };
 
 struct platform_device msm_cpu_fe = {
@@ -3219,3 +3223,50 @@
 };
 
 #endif
+
+static int msm8960_LPM_latency = 1000; /* >100 usec for WFI */
+
+struct platform_device msm8960_cpu_idle_device = {
+	.name   = "msm_cpu_idle",
+	.id     = -1,
+	.dev = {
+		.platform_data = &msm8960_LPM_latency,
+	},
+};
+
+static struct msm_dcvs_freq_entry msm8960_freq[] = {
+	{ 384000, 166981,  345600},
+	{ 702000, 213049,  632502},
+	{1026000, 285712,  925613},
+	{1242000, 383945, 1176550},
+	{1458000, 419729, 1465478},
+	{1512000, 434116, 1546674},
+
+};
+
+static struct msm_dcvs_core_info msm8960_core_info = {
+	.freq_tbl = &msm8960_freq[0],
+	.core_param = {
+		.max_time_us = 100000,
+		.num_freq = ARRAY_SIZE(msm8960_freq),
+	},
+	.algo_param = {
+		.slack_time_us = 58000,
+		.scale_slack_time = 0,
+		.scale_slack_time_pct = 0,
+		.disable_pc_threshold = 1458000,
+		.em_window_size = 100000,
+		.em_max_util_pct = 97,
+		.ss_window_size = 1000000,
+		.ss_util_pct = 95,
+		.ss_iobusy_conv = 100,
+	},
+};
+
+struct platform_device msm8960_msm_gov_device = {
+	.name = "msm_dcvs_gov",
+	.id = -1,
+	.dev = {
+		.platform_data = &msm8960_core_info,
+	},
+};
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 331fc26..bb0d9b9 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -17,6 +17,8 @@
 #include <linux/io.h>
 #include <linux/platform_data/qcom_crypto_device.h>
 #include <linux/dma-mapping.h>
+#include <sound/msm-dai-q6.h>
+#include <sound/apr_audio.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/flash.h>
 #include <mach/board.h>
@@ -387,6 +389,124 @@
 	},
 };
 
+struct platform_device msm_pcm = {
+	.name	= "msm-pcm-dsp",
+	.id	= -1,
+};
+
+struct platform_device msm_multi_ch_pcm = {
+	.name	= "msm-multi-ch-pcm-dsp",
+	.id	= -1,
+};
+
+struct platform_device msm_pcm_routing = {
+	.name	= "msm-pcm-routing",
+	.id	= -1,
+};
+
+struct platform_device msm_cpudai0 = {
+	.name	= "msm-dai-q6",
+	.id	= 0x4000,
+};
+
+struct platform_device msm_cpudai1 = {
+	.name	= "msm-dai-q6",
+	.id	= 0x4001,
+};
+
+struct platform_device msm_cpudai_bt_rx = {
+	.name   = "msm-dai-q6",
+	.id     = 0x3000,
+};
+
+struct platform_device msm_cpudai_bt_tx = {
+	.name   = "msm-dai-q6",
+	.id     = 0x3001,
+};
+
+/*
+ * Machine specific data for AUX PCM Interface
+ * which the driver will  be unware of.
+ */
+struct msm_dai_auxpcm_pdata auxpcm_rx_pdata = {
+	.clk = "pcm_clk",
+	.mode = AFE_PCM_CFG_MODE_PCM,
+	.sync = AFE_PCM_CFG_SYNC_INT,
+	.frame = AFE_PCM_CFG_FRM_256BPF,
+	.quant = AFE_PCM_CFG_QUANT_LINEAR_NOPAD,
+	.slot = 0,
+	.data = AFE_PCM_CFG_CDATAOE_MASTER,
+	.pcm_clk_rate = 2048000,
+};
+
+struct platform_device msm_cpudai_auxpcm_rx = {
+	.name = "msm-dai-q6",
+	.id = 2,
+	.dev = {
+		.platform_data = &auxpcm_rx_pdata,
+	},
+};
+
+struct platform_device msm_cpudai_auxpcm_tx = {
+	.name = "msm-dai-q6",
+	.id = 3,
+};
+
+struct platform_device msm_cpu_fe = {
+	.name	= "msm-dai-fe",
+	.id	= -1,
+};
+
+struct platform_device msm_stub_codec = {
+	.name	= "msm-stub-codec",
+	.id	= 1,
+};
+
+struct platform_device msm_voice = {
+	.name	= "msm-pcm-voice",
+	.id	= -1,
+};
+
+struct platform_device msm_voip = {
+	.name	= "msm-voip-dsp",
+	.id	= -1,
+};
+
+struct platform_device msm_compr_dsp = {
+	.name	= "msm-compr-dsp",
+	.id	= -1,
+};
+
+struct platform_device msm_pcm_hostless = {
+	.name	= "msm-pcm-hostless",
+	.id	= -1,
+};
+
+struct platform_device msm_cpudai_afe_01_rx = {
+	.name = "msm-dai-q6",
+	.id = 0xE0,
+};
+
+struct platform_device msm_cpudai_afe_01_tx = {
+	.name = "msm-dai-q6",
+	.id = 0xF0,
+};
+
+struct platform_device msm_cpudai_afe_02_rx = {
+	.name = "msm-dai-q6",
+	.id = 0xF1,
+};
+
+struct platform_device msm_cpudai_afe_02_tx = {
+	.name = "msm-dai-q6",
+	.id = 0xE1,
+};
+
+struct platform_device msm_pcm_afe = {
+	.name	= "msm-pcm-afe",
+	.id	= -1,
+};
+
 static struct resource resources_ssbi_pmic1[] = {
 	{
 		.start  = MSM_PMIC1_SSBI_CMD_PHYS,
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
index 057a006..96ee564 100644
--- a/arch/arm/mach-msm/devices-iommu.c
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -995,59 +995,45 @@
 	}
 
 	/* Initialize common devs */
-	ret = platform_add_devices(msm_iommu_common_devs,
-			 ARRAY_SIZE(msm_iommu_common_devs));
-	if (ret != 0)
-		goto failure2;
+	platform_add_devices(msm_iommu_common_devs,
+				ARRAY_SIZE(msm_iommu_common_devs));
 
 	/* Initialize soc-specific devs */
-	if (cpu_is_apq8064()) {
-		ret = platform_add_devices(msm_iommu_8064_devs,
-				 ARRAY_SIZE(msm_iommu_8064_devs));
-	} else {
-		ret = platform_add_devices(msm_iommu_gfx2d_devs,
-				 ARRAY_SIZE(msm_iommu_gfx2d_devs));
+	if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+		platform_add_devices(msm_iommu_jpegd_devs,
+				ARRAY_SIZE(msm_iommu_jpegd_devs));
+		platform_add_devices(msm_iommu_gfx2d_devs,
+				ARRAY_SIZE(msm_iommu_gfx2d_devs));
 	}
-	if (ret != 0)
-		goto failure2;
 
-	if (!cpu_is_msm8930()) {
-		ret = platform_add_devices(msm_iommu_jpegd_devs,
-			ARRAY_SIZE(msm_iommu_jpegd_devs));
-
-		if (ret != 0)
-			goto failure2;
+	if (cpu_is_apq8064()) {
+		platform_add_devices(msm_iommu_jpegd_devs,
+				ARRAY_SIZE(msm_iommu_jpegd_devs));
+		platform_add_devices(msm_iommu_8064_devs,
+				ARRAY_SIZE(msm_iommu_8064_devs));
 	}
 
 	/* Initialize common ctx_devs */
 	ret = platform_add_devices(msm_iommu_common_ctx_devs,
-				 ARRAY_SIZE(msm_iommu_common_ctx_devs));
-	if (ret != 0)
-		goto failure2;
+				ARRAY_SIZE(msm_iommu_common_ctx_devs));
 
 	/* Initialize soc-specific ctx_devs */
-	if (cpu_is_apq8064()) {
-		ret = platform_add_devices(msm_iommu_8064_ctx_devs,
-				ARRAY_SIZE(msm_iommu_8064_ctx_devs));
-	} else {
-		ret = platform_add_devices(msm_iommu_gfx2d_ctx_devs,
-					ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs));
+	if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+		platform_add_devices(msm_iommu_jpegd_ctx_devs,
+				ARRAY_SIZE(msm_iommu_jpegd_ctx_devs));
+		platform_add_devices(msm_iommu_gfx2d_ctx_devs,
+				ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs));
 	}
-	if (ret != 0)
-		goto failure2;
 
-	if (!cpu_is_msm8930()) {
-		ret = platform_add_devices(msm_iommu_jpegd_ctx_devs,
-			ARRAY_SIZE(msm_iommu_jpegd_ctx_devs));
-
-		if (ret != 0)
-			goto failure2;
+	if (cpu_is_apq8064()) {
+		platform_add_devices(msm_iommu_jpegd_ctx_devs,
+				ARRAY_SIZE(msm_iommu_jpegd_ctx_devs));
+		platform_add_devices(msm_iommu_8064_ctx_devs,
+				ARRAY_SIZE(msm_iommu_8064_ctx_devs));
 	}
 
 	return 0;
 
-failure2:
-	platform_device_unregister(&msm_root_iommu_dev);
 failure:
 	return ret;
 }
@@ -1060,34 +1046,34 @@
 	for (i = 0; i < ARRAY_SIZE(msm_iommu_common_ctx_devs); i++)
 		platform_device_unregister(msm_iommu_common_ctx_devs[i]);
 
-	/* soc-specific ctx_devs. */
-	if (cpu_is_apq8064()) {
-		for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_ctx_devs); i++)
-			platform_device_unregister(msm_iommu_8064_ctx_devs[i]);
-	} else {
-		for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs); i++)
-			platform_device_unregister(msm_iommu_gfx2d_ctx_devs[i]);
-	}
-
-	if (!cpu_is_msm8930()) {
-		for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_ctx_devs); i++)
-			platform_device_unregister(msm_iommu_jpegd_ctx_devs[i]);
-	}
-
 	/* Common devs. */
 	for (i = 0; i < ARRAY_SIZE(msm_iommu_common_devs); ++i)
 		platform_device_unregister(msm_iommu_common_devs[i]);
 
-	/* soc-specific devs. */
-	if (cpu_is_apq8064()) {
-		for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_devs); i++)
-			platform_device_unregister(msm_iommu_8064_devs[i]);
-	} else {
+	if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_ctx_devs); i++)
+			platform_device_unregister(msm_iommu_gfx2d_ctx_devs[i]);
+
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_ctx_devs); i++)
+			platform_device_unregister(msm_iommu_jpegd_ctx_devs[i]);
+
 		for (i = 0; i < ARRAY_SIZE(msm_iommu_gfx2d_devs); i++)
 			platform_device_unregister(msm_iommu_gfx2d_devs[i]);
+
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_devs); i++)
+			platform_device_unregister(msm_iommu_jpegd_devs[i]);
 	}
 
-	if (!cpu_is_msm8930()) {
+	if (cpu_is_apq8064()) {
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_ctx_devs); i++)
+			platform_device_unregister(msm_iommu_8064_ctx_devs[i]);
+
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_ctx_devs); i++)
+			platform_device_unregister(msm_iommu_jpegd_ctx_devs[i]);
+
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_8064_devs); i++)
+			platform_device_unregister(msm_iommu_8064_devs[i]);
+
 		for (i = 0; i < ARRAY_SIZE(msm_iommu_jpegd_devs); i++)
 			platform_device_unregister(msm_iommu_jpegd_devs[i]);
 	}
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index aa09056..199ff85 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -330,3 +330,17 @@
 extern struct platform_device msm_dsps_device_8064;
 extern struct platform_device *msm_copper_stub_regulator_devices[];
 extern int msm_copper_stub_regulator_devices_len;
+
+extern struct platform_device msm8960_cpu_idle_device;
+extern struct platform_device msm8930_cpu_idle_device;
+extern struct platform_device apq8064_cpu_idle_device;
+
+extern struct platform_device msm8960_msm_gov_device;
+extern struct platform_device msm8930_msm_gov_device;
+extern struct platform_device apq8064_msm_gov_device;
+
+extern struct platform_device msm_bus_8930_apps_fabric;
+extern struct platform_device msm_bus_8930_sys_fabric;
+extern struct platform_device msm_bus_8930_mm_fabric;
+extern struct platform_device msm_bus_8930_sys_fpb;
+extern struct platform_device msm_bus_8930_cpss_fpb;
diff --git a/arch/arm/mach-msm/gss-8064.c b/arch/arm/mach-msm/gss-8064.c
new file mode 100644
index 0000000..1ddb7a3
--- /dev/null
+++ b/arch/arm/mach-msm/gss-8064.c
@@ -0,0 +1,259 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+
+#include <mach/irqs.h>
+#include <mach/scm.h>
+#include <mach/peripheral-loader.h>
+#include <mach/subsystem_restart.h>
+#include <mach/subsystem_notif.h>
+#include <mach/socinfo.h>
+
+#include "smd_private.h"
+#include "modem_notifier.h"
+#include "ramdump.h"
+
+static struct gss_8064_data {
+	struct miscdevice gss_dev;
+	void *pil_handle;
+	void *gss_ramdump_dev;
+	void *smem_ramdump_dev;
+} gss_data;
+
+static int crash_shutdown;
+
+static void gss_fatal_fn(struct work_struct *work)
+{
+	uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
+	uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
+					SMSM_SYSTEM_PWRDWN_USR;
+	uint32_t gss_state;
+
+	pr_err("Watchdog bite received from GSS!\n");
+
+	gss_state = smsm_get_state(SMSM_MODEM_STATE);
+
+	if (gss_state & panic_smsm_states) {
+
+		pr_err("GSS SMSM state changed to SMSM_RESET.\n"
+			"Probable err_fatal on the GSS. "
+			"Calling subsystem restart...\n");
+		subsystem_restart("gss");
+
+	} else if (gss_state & reset_smsm_states) {
+
+		pr_err("%s: User-invoked system reset/powerdown. "
+			"Resetting the SoC now.\n",
+			__func__);
+		kernel_restart(NULL);
+	} else {
+		/* TODO: Bus unlock code/sequence goes _here_ */
+		subsystem_restart("gss");
+	}
+}
+
+static DECLARE_WORK(gss_fatal_work, gss_fatal_fn);
+
+static void smsm_state_cb(void *data, uint32_t old_state, uint32_t new_state)
+{
+	/* Ignore if we're the one that set SMSM_RESET */
+	if (crash_shutdown)
+		return;
+
+	if (new_state & SMSM_RESET) {
+		pr_err("GSS SMSM state changed to SMSM_RESET.\n"
+			"Probable err_fatal on the GSS. "
+			"Calling subsystem restart...\n");
+		subsystem_restart("gss");
+	}
+}
+
+#define Q6_FW_WDOG_ENABLE		0x08882024
+#define Q6_SW_WDOG_ENABLE		0x08982024
+static int gss_shutdown(const struct subsys_data *subsys)
+{
+	pil_force_shutdown("gss");
+	disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
+
+	return 0;
+}
+
+static int gss_powerup(const struct subsys_data *subsys)
+{
+	pil_force_boot("gss");
+	enable_irq(GSS_A5_WDOG_EXPIRED);
+	return 0;
+}
+
+void gss_crash_shutdown(const struct subsys_data *subsys)
+{
+	crash_shutdown = 1;
+	smsm_reset_modem(SMSM_RESET);
+}
+
+/* FIXME: Get address, size from PIL */
+static struct ramdump_segment gss_segments[] = {
+	{0x89D00000 - 0x89000000}
+};
+
+static struct ramdump_segment smem_segments[] = {
+	{0x80000000, 0x00200000},
+};
+
+static int gss_ramdump(int enable,
+				const struct subsys_data *crashed_subsys)
+{
+	int ret = 0;
+
+	if (enable) {
+		ret = do_ramdump(gss_data.gss_ramdump_dev, gss_segments,
+			ARRAY_SIZE(gss_segments));
+
+		if (ret < 0) {
+			pr_err("Unable to dump gss memory (rc = %d).\n",
+			       ret);
+			goto out;
+		}
+
+		ret = do_ramdump(gss_data.smem_ramdump_dev, smem_segments,
+			ARRAY_SIZE(smem_segments));
+
+		if (ret < 0) {
+			pr_err("Unable to dump smem memory (rc = %d).\n", ret);
+			goto out;
+		}
+	}
+
+out:
+	return ret;
+}
+
+static irqreturn_t gss_wdog_bite_irq(int irq, void *dev_id)
+{
+	schedule_work(&gss_fatal_work);
+	disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
+
+	return IRQ_HANDLED;
+}
+
+static struct subsys_data gss_8064 = {
+	.name = "gss",
+	.shutdown = gss_shutdown,
+	.powerup = gss_powerup,
+	.ramdump = gss_ramdump,
+	.crash_shutdown = gss_crash_shutdown
+};
+
+static int gss_subsystem_restart_init(void)
+{
+	return ssr_register_subsystem(&gss_8064);
+}
+
+static int gss_open(struct inode *inode, struct file *filep)
+{
+	void *ret;
+	gss_data.pil_handle = ret = pil_get("gss");
+	if (!ret)
+		pr_debug("%s - pil_get returned NULL\n", __func__);
+	return 0;
+}
+
+static int gss_release(struct inode *inode, struct file *filep)
+{
+	pil_put(gss_data.pil_handle);
+	pr_debug("%s pil_put called on GSS\n", __func__);
+	return 0;
+}
+
+const struct file_operations gss_file_ops = {
+	.open = gss_open,
+	.release = gss_release,
+};
+
+static int __init gss_8064_init(void)
+{
+	int ret;
+
+	if (!cpu_is_apq8064())
+		return -ENODEV;
+
+	ret = smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
+		smsm_state_cb, 0);
+
+	if (ret < 0)
+		pr_err("%s: Unable to register SMSM callback! (%d)\n",
+				__func__, ret);
+
+	ret = request_irq(GSS_A5_WDOG_EXPIRED, gss_wdog_bite_irq,
+			IRQF_TRIGGER_RISING, "gss_a5_wdog", NULL);
+
+	if (ret < 0) {
+		pr_err("%s: Unable to request gss watchdog IRQ. (%d)\n",
+				__func__, ret);
+		disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
+		goto out;
+	}
+
+	ret = gss_subsystem_restart_init();
+
+	if (ret < 0) {
+		pr_err("%s: Unable to reg with subsystem restart. (%d)\n",
+				__func__, ret);
+		goto out;
+	}
+
+	gss_data.gss_dev.minor = MISC_DYNAMIC_MINOR;
+	gss_data.gss_dev.name = "gss";
+	gss_data.gss_dev.fops = &gss_file_ops;
+	ret = misc_register(&gss_data.gss_dev);
+
+	if (ret) {
+		pr_err("%s: misc_registers failed for %s (%d)", __func__,
+				gss_data.gss_dev.name, ret);
+		goto out;
+	}
+
+	gss_data.gss_ramdump_dev = create_ramdump_device("gss");
+
+	if (!gss_data.gss_ramdump_dev) {
+		pr_err("%s: Unable to create gss ramdump device. (%d)\n",
+				__func__, -ENOMEM);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	gss_data.smem_ramdump_dev = create_ramdump_device("smem");
+
+	if (!gss_data.smem_ramdump_dev) {
+		pr_err("%s: Unable to create smem ramdump device. (%d)\n",
+				__func__, -ENOMEM);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pr_info("%s: gss fatal driver init'ed.\n", __func__);
+out:
+	return ret;
+}
+
+module_init(gss_8064_init);
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 8d40908..8a1ff35 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -15,10 +15,10 @@
 #include <asm/cacheflush.h>
 #include <asm/vfp.h>
 
+#include <mach/qdss.h>
 #include <mach/msm_rtb.h>
 
 #include "pm.h"
-#include "qdss.h"
 #include "spm.h"
 
 extern volatile int pen_release;
diff --git a/arch/arm/mach-msm/include/mach/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index cd8f2a3..6252cef 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -185,7 +185,9 @@
 #define NR_MSM_IRQS 288
 #define NR_GPIO_IRQS 88
 #define NR_PM8018_IRQS 256
-#define NR_BOARD_IRQS NR_PM8018_IRQS
+#define NR_WCD9XXX_IRQS 49
+#define NR_TABLA_IRQS NR_WCD9XXX_IRQS
+#define NR_BOARD_IRQS (NR_PM8018_IRQS + NR_WCD9XXX_IRQS)
 #define NR_TLMM_MSM_DIR_CONN_IRQ 8 /*Need to Verify this Count*/
 #define NR_MSM_GPIOS NR_GPIO_IRQS
 
diff --git a/arch/arm/mach-msm/include/mach/msm_bus_board.h b/arch/arm/mach-msm/include/mach/msm_bus_board.h
index fd61c98..f62bc86 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus_board.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus_board.h
@@ -72,6 +72,13 @@
 
 extern struct msm_bus_fabric_registration msm_bus_9615_sys_fabric_pdata;
 extern struct msm_bus_fabric_registration msm_bus_9615_def_fab_pdata;
+
+extern struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata;
+extern struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata;
+
 void msm_bus_rpm_set_mt_mask(void);
 int msm_bus_board_rpm_get_il_ids(uint16_t *id);
 int msm_bus_board_get_iid(int id);
diff --git a/arch/arm/mach-msm/include/mach/qdss.h b/arch/arm/mach-msm/include/mach/qdss.h
new file mode 100644
index 0000000..530bcb2
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdss.h
@@ -0,0 +1,32 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_QDSS_H
+#define __MACH_QDSS_H
+
+#ifdef CONFIG_MSM_QDSS
+extern int qdss_clk_enable(void);
+extern void qdss_clk_disable(void);
+#else
+static inline int qdss_clk_enable(void) { return -ENOSYS; }
+static inline void qdss_clk_disable(void) {}
+#endif
+
+#ifdef CONFIG_MSM_JTAG
+extern void msm_jtag_save_state(void);
+extern void msm_jtag_restore_state(void);
+#else
+static inline void msm_jtag_save_state(void) {}
+static inline void msm_jtag_restore_state(void) {}
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/rpm-8930.h b/arch/arm/mach-msm/include/mach/rpm-8930.h
index 3bcd42e..0211b67 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8930.h
@@ -141,106 +141,106 @@
 	MSM_RPM_8930_ID_APPS_FABRIC_CFG_CLKMOD_2		= 39,
 	MSM_RPM_8930_ID_APPS_FABRIC_CFG_IOCTL			= 40,
 	MSM_RPM_8930_ID_APPS_FABRIC_ARB_0			= 41,
-	MSM_RPM_8930_ID_APPS_FABRIC_ARB_11 =
-		MSM_RPM_8930_ID_APPS_FABRIC_ARB_0 + 11,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_0			= 53,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_1			= 54,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_0			= 55,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_1			= 56,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_2			= 57,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_IOCTL			= 58,
-	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0			= 59,
-	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_28 =
-		MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 + 28,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_0			= 88,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_1			= 89,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_0		= 90,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_1		= 91,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_2		= 92,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_IOCTL			= 93,
-	MSM_RPM_8930_ID_MM_FABRIC_ARB_0				= 94,
-	MSM_RPM_8930_ID_MM_FABRIC_ARB_22 =
-		MSM_RPM_8930_ID_MM_FABRIC_ARB_0	+ 22,
+	MSM_RPM_8930_ID_APPS_FABRIC_ARB_5 =
+		MSM_RPM_8930_ID_APPS_FABRIC_ARB_0 + 5,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_0			= 47,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_1			= 48,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_0			= 49,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_1			= 50,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_2			= 51,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_IOCTL			= 52,
+	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0			= 53,
+	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_19 =
+		MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 + 19,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_0			= 73,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_1			= 74,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_0		= 75,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_1		= 76,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_2		= 77,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_IOCTL			= 78,
+	MSM_RPM_8930_ID_MM_FABRIC_ARB_0				= 79,
+	MSM_RPM_8930_ID_MM_FABRIC_ARB_10 =
+		MSM_RPM_8930_ID_MM_FABRIC_ARB_0	+ 10,
 
-	MSM_RPM_8930_ID_PM8038_S1_0				= 117,
-	MSM_RPM_8930_ID_PM8038_S1_1				= 118,
-	MSM_RPM_8930_ID_PM8038_S2_0				= 119,
-	MSM_RPM_8930_ID_PM8038_S2_1				= 120,
-	MSM_RPM_8930_ID_PM8038_S3_0				= 121,
-	MSM_RPM_8930_ID_PM8038_S3_1				= 122,
-	MSM_RPM_8930_ID_PM8038_S4_0				= 123,
-	MSM_RPM_8930_ID_PM8038_S4_1				= 124,
-	MSM_RPM_8930_ID_PM8038_S5_0				= 125,
-	MSM_RPM_8930_ID_PM8038_S5_1				= 126,
-	MSM_RPM_8930_ID_PM8038_S6_0				= 127,
-	MSM_RPM_8930_ID_PM8038_S6_1				= 128,
-	MSM_RPM_8930_ID_PM8038_L1_0				= 129,
-	MSM_RPM_8930_ID_PM8038_L1_1				= 130,
-	MSM_RPM_8930_ID_PM8038_L2_0				= 131,
-	MSM_RPM_8930_ID_PM8038_L2_1				= 132,
-	MSM_RPM_8930_ID_PM8038_L3_0				= 133,
-	MSM_RPM_8930_ID_PM8038_L3_1				= 134,
-	MSM_RPM_8930_ID_PM8038_L4_0				= 135,
-	MSM_RPM_8930_ID_PM8038_L4_1				= 136,
-	MSM_RPM_8930_ID_PM8038_L5_0				= 137,
-	MSM_RPM_8930_ID_PM8038_L5_1				= 138,
-	MSM_RPM_8930_ID_PM8038_L6_0				= 139,
-	MSM_RPM_8930_ID_PM8038_L6_1				= 140,
-	MSM_RPM_8930_ID_PM8038_L7_0				= 141,
-	MSM_RPM_8930_ID_PM8038_L7_1				= 142,
-	MSM_RPM_8930_ID_PM8038_L8_0				= 143,
-	MSM_RPM_8930_ID_PM8038_L8_1				= 144,
-	MSM_RPM_8930_ID_PM8038_L9_0				= 145,
-	MSM_RPM_8930_ID_PM8038_L9_1				= 146,
-	MSM_RPM_8930_ID_PM8038_L10_0				= 147,
-	MSM_RPM_8930_ID_PM8038_L10_1				= 148,
-	MSM_RPM_8930_ID_PM8038_L11_0				= 149,
-	MSM_RPM_8930_ID_PM8038_L11_1				= 150,
-	MSM_RPM_8930_ID_PM8038_L12_0				= 151,
-	MSM_RPM_8930_ID_PM8038_L12_1				= 152,
-	MSM_RPM_8930_ID_PM8038_L13_0				= 153,
-	MSM_RPM_8930_ID_PM8038_L13_1				= 154,
-	MSM_RPM_8930_ID_PM8038_L14_0				= 155,
-	MSM_RPM_8930_ID_PM8038_L14_1				= 156,
-	MSM_RPM_8930_ID_PM8038_L15_0				= 157,
-	MSM_RPM_8930_ID_PM8038_L15_1				= 158,
-	MSM_RPM_8930_ID_PM8038_L16_0				= 159,
-	MSM_RPM_8930_ID_PM8038_L16_1				= 160,
-	MSM_RPM_8930_ID_PM8038_L17_0				= 161,
-	MSM_RPM_8930_ID_PM8038_L17_1				= 162,
-	MSM_RPM_8930_ID_PM8038_L18_0				= 163,
-	MSM_RPM_8930_ID_PM8038_L18_1				= 164,
-	MSM_RPM_8930_ID_PM8038_L19_0				= 165,
-	MSM_RPM_8930_ID_PM8038_L19_1				= 166,
-	MSM_RPM_8930_ID_PM8038_L20_0				= 167,
-	MSM_RPM_8930_ID_PM8038_L20_1				= 168,
-	MSM_RPM_8930_ID_PM8038_L21_0				= 169,
-	MSM_RPM_8930_ID_PM8038_L21_1				= 170,
-	MSM_RPM_8930_ID_PM8038_L22_0				= 171,
-	MSM_RPM_8930_ID_PM8038_L22_1				= 172,
-	MSM_RPM_8930_ID_PM8038_L23_0				= 173,
-	MSM_RPM_8930_ID_PM8038_L23_1				= 174,
-	MSM_RPM_8930_ID_PM8038_L24_0				= 175,
-	MSM_RPM_8930_ID_PM8038_L24_1				= 176,
-	MSM_RPM_8930_ID_PM8038_L25_0				= 177,
-	MSM_RPM_8930_ID_PM8038_L25_1				= 178,
-	MSM_RPM_8930_ID_PM8038_L26_0				= 179,
-	MSM_RPM_8930_ID_PM8038_L26_1				= 180,
-	MSM_RPM_8930_ID_PM8038_L27_0				= 181,
-	MSM_RPM_8930_ID_PM8038_L27_1				= 182,
-	MSM_RPM_8930_ID_PM8038_CLK1_0				= 183,
-	MSM_RPM_8930_ID_PM8038_CLK1_1				= 184,
-	MSM_RPM_8930_ID_PM8038_CLK2_0				= 185,
-	MSM_RPM_8930_ID_PM8038_CLK2_1				= 186,
-	MSM_RPM_8930_ID_PM8038_LVS1				= 187,
-	MSM_RPM_8930_ID_PM8038_LVS2				= 188,
-	MSM_RPM_8930_ID_NCP_0					= 189,
-	MSM_RPM_8930_ID_NCP_1					= 190,
-	MSM_RPM_8930_ID_CXO_BUFFERS				= 191,
-	MSM_RPM_8930_ID_USB_OTG_SWITCH				= 192,
-	MSM_RPM_8930_ID_HDMI_SWITCH				= 193,
-	MSM_RPM_8930_ID_QDSS_CLK				= 194,
-	MSM_RPM_8930_ID_VOLTAGE_CORNER				= 195,
+	MSM_RPM_8930_ID_PM8038_S1_0	= 90,
+	MSM_RPM_8930_ID_PM8038_S1_1	= 91,
+	MSM_RPM_8930_ID_PM8038_S2_0	= 92,
+	MSM_RPM_8930_ID_PM8038_S2_1	= 93,
+	MSM_RPM_8930_ID_PM8038_S3_0	= 94,
+	MSM_RPM_8930_ID_PM8038_S3_1	= 95,
+	MSM_RPM_8930_ID_PM8038_S4_0	= 96,
+	MSM_RPM_8930_ID_PM8038_S4_1	= 97,
+	MSM_RPM_8930_ID_PM8038_S5_0	= 98,
+	MSM_RPM_8930_ID_PM8038_S5_1	= 99,
+	MSM_RPM_8930_ID_PM8038_S6_0	= 100,
+	MSM_RPM_8930_ID_PM8038_S6_1	= 101,
+	MSM_RPM_8930_ID_PM8038_L1_0	= 102,
+	MSM_RPM_8930_ID_PM8038_L1_1	= 103,
+	MSM_RPM_8930_ID_PM8038_L2_0	= 104,
+	MSM_RPM_8930_ID_PM8038_L2_1	= 105,
+	MSM_RPM_8930_ID_PM8038_L3_0	= 106,
+	MSM_RPM_8930_ID_PM8038_L3_1	= 107,
+	MSM_RPM_8930_ID_PM8038_L4_0	= 108,
+	MSM_RPM_8930_ID_PM8038_L4_1	= 109,
+	MSM_RPM_8930_ID_PM8038_L5_0	= 110,
+	MSM_RPM_8930_ID_PM8038_L5_1	= 111,
+	MSM_RPM_8930_ID_PM8038_L6_0	= 112,
+	MSM_RPM_8930_ID_PM8038_L6_1	= 113,
+	MSM_RPM_8930_ID_PM8038_L7_0	= 114,
+	MSM_RPM_8930_ID_PM8038_L7_1	= 115,
+	MSM_RPM_8930_ID_PM8038_L8_0	= 116,
+	MSM_RPM_8930_ID_PM8038_L8_1	= 117,
+	MSM_RPM_8930_ID_PM8038_L9_0	= 118,
+	MSM_RPM_8930_ID_PM8038_L9_1	= 119,
+	MSM_RPM_8930_ID_PM8038_L10_0	= 120,
+	MSM_RPM_8930_ID_PM8038_L10_1	= 121,
+	MSM_RPM_8930_ID_PM8038_L11_0	= 122,
+	MSM_RPM_8930_ID_PM8038_L11_1	= 123,
+	MSM_RPM_8930_ID_PM8038_L12_0	= 124,
+	MSM_RPM_8930_ID_PM8038_L12_1	= 125,
+	MSM_RPM_8930_ID_PM8038_L13_0	= 126,
+	MSM_RPM_8930_ID_PM8038_L13_1	= 127,
+	MSM_RPM_8930_ID_PM8038_L14_0	= 128,
+	MSM_RPM_8930_ID_PM8038_L14_1	= 129,
+	MSM_RPM_8930_ID_PM8038_L15_0	= 130,
+	MSM_RPM_8930_ID_PM8038_L15_1	= 131,
+	MSM_RPM_8930_ID_PM8038_L16_0	= 132,
+	MSM_RPM_8930_ID_PM8038_L16_1	= 133,
+	MSM_RPM_8930_ID_PM8038_L17_0	= 134,
+	MSM_RPM_8930_ID_PM8038_L17_1	= 135,
+	MSM_RPM_8930_ID_PM8038_L18_0	= 136,
+	MSM_RPM_8930_ID_PM8038_L18_1	= 137,
+	MSM_RPM_8930_ID_PM8038_L19_0	= 138,
+	MSM_RPM_8930_ID_PM8038_L19_1	= 139,
+	MSM_RPM_8930_ID_PM8038_L20_0	= 140,
+	MSM_RPM_8930_ID_PM8038_L20_1	= 141,
+	MSM_RPM_8930_ID_PM8038_L21_0	= 142,
+	MSM_RPM_8930_ID_PM8038_L21_1	= 143,
+	MSM_RPM_8930_ID_PM8038_L22_0	= 144,
+	MSM_RPM_8930_ID_PM8038_L22_1	= 145,
+	MSM_RPM_8930_ID_PM8038_L23_0	= 146,
+	MSM_RPM_8930_ID_PM8038_L23_1	= 147,
+	MSM_RPM_8930_ID_PM8038_L24_0	= 148,
+	MSM_RPM_8930_ID_PM8038_L24_1	= 149,
+	MSM_RPM_8930_ID_PM8038_L25_0	= 150,
+	MSM_RPM_8930_ID_PM8038_L25_1	= 151,
+	MSM_RPM_8930_ID_PM8038_L26_0	= 152,
+	MSM_RPM_8930_ID_PM8038_L26_1	= 153,
+	MSM_RPM_8930_ID_PM8038_L27_0	= 154,
+	MSM_RPM_8930_ID_PM8038_L27_1	= 155,
+	MSM_RPM_8930_ID_PM8038_CLK1_0	= 156,
+	MSM_RPM_8930_ID_PM8038_CLK1_1	= 157,
+	MSM_RPM_8930_ID_PM8038_CLK2_0	= 158,
+	MSM_RPM_8930_ID_PM8038_CLK2_1	= 159,
+	MSM_RPM_8930_ID_PM8038_LVS1	= 160,
+	MSM_RPM_8930_ID_PM8038_LVS2	= 161,
+	MSM_RPM_8930_ID_NCP_0	= 162,
+	MSM_RPM_8930_ID_NCP_1	= 163,
+	MSM_RPM_8930_ID_CXO_BUFFERS	= 164,
+	MSM_RPM_8930_ID_USB_OTG_SWITCH	= 165,
+	MSM_RPM_8930_ID_HDMI_SWITCH	= 166,
+	MSM_RPM_8930_ID_QDSS_CLK	= 167,
+	MSM_RPM_8930_ID_VOLTAGE_CORNER	= 168,
 	MSM_RPM_8930_ID_LAST = MSM_RPM_8930_ID_VOLTAGE_CORNER,
 };
 
diff --git a/arch/arm/mach-msm/include/mach/scm.h b/arch/arm/mach-msm/include/mach/scm.h
index af4691a..7cc5f7a 100644
--- a/arch/arm/mach-msm/include/mach/scm.h
+++ b/arch/arm/mach-msm/include/mach/scm.h
@@ -38,6 +38,7 @@
 
 extern u32 scm_get_version(void);
 extern int scm_is_call_available(u32 svc_id, u32 cmd_id);
+extern int scm_get_feat_version(u32 feat);
 
 #else
 
@@ -73,5 +74,10 @@
 	return 0;
 }
 
+static inline int scm_get_feat_version(u32 feat)
+{
+	return 0;
+}
+
 #endif
 #endif
diff --git a/arch/arm/mach-msm/include/mach/timex.h b/arch/arm/mach-msm/include/mach/timex.h
index ca7c4c7..542aba3 100644
--- a/arch/arm/mach-msm/include/mach/timex.h
+++ b/arch/arm/mach-msm/include/mach/timex.h
@@ -18,6 +18,8 @@
 
 #define CLOCK_TICK_RATE		1000000
 
+#ifdef CONFIG_HAVE_ARCH_HAS_CURRENT_TIMER
 #define ARCH_HAS_READ_CURRENT_TIMER
+#endif
 
 #endif
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
index 853888a..a310ba0 100644
--- a/arch/arm/mach-msm/iommu.c
+++ b/arch/arm/mach-msm/iommu.c
@@ -685,6 +685,19 @@
 	return ret;
 }
 
+static unsigned int get_phys_addr(struct scatterlist *sg)
+{
+	/*
+	 * Try sg_dma_address first so that we can
+	 * map carveout regions that do not have a
+	 * struct page associated with them.
+	 */
+	unsigned int pa = sg_dma_address(sg);
+	if (pa == 0)
+		pa = sg_phys(sg);
+	return pa;
+}
+
 static int msm_iommu_map_range(struct iommu_domain *domain, unsigned int va,
 			       struct scatterlist *sg, unsigned int len,
 			       int prot)
@@ -722,7 +735,12 @@
 	sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
 	sl_offset = SL_OFFSET(va);
 
-	chunk_pa = sg_phys(sg);
+	chunk_pa = get_phys_addr(sg);
+	if (chunk_pa == 0) {
+		pr_debug("No dma address for sg %p\n", sg);
+		ret = -EINVAL;
+		goto fail;
+	}
 
 	while (offset < len) {
 		/* Set up a 2nd level page table if one doesn't exist */
@@ -764,7 +782,13 @@
 			if (chunk_offset >= sg->length && offset < len) {
 				chunk_offset = 0;
 				sg = sg_next(sg);
-				chunk_pa = sg_phys(sg);
+				chunk_pa = get_phys_addr(sg);
+				if (chunk_pa == 0) {
+					pr_debug("No dma address for sg %p\n",
+						 sg);
+					ret = -EINVAL;
+					goto fail;
+				}
 			}
 		}
 
diff --git a/arch/arm/mach-msm/jtag.c b/arch/arm/mach-msm/jtag.c
index a2ec89b..8dae9c6 100644
--- a/arch/arm/mach-msm/jtag.c
+++ b/arch/arm/mach-msm/jtag.c
@@ -16,21 +16,26 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
+#include <linux/export.h>
 #include <linux/printk.h>
 #include <linux/ratelimit.h>
+#include <mach/scm.h>
 
-#include "qdss.h"
+#include "qdss-priv.h"
 #include "cp14.h"
 
- /* no of dbg regs + 1 (for storing the reg count) */
+/* no of dbg regs + 1 (for storing the reg count) */
 #define MAX_DBG_REGS		(90)
 #define MAX_DBG_STATE_SIZE	(MAX_DBG_REGS * num_possible_cpus())
- /* no of etm regs + 1 (for storing the reg count) */
+/* no of etm regs + 1 (for storing the reg count) */
 #define MAX_ETM_REGS		(78)
 #define MAX_ETM_STATE_SIZE	(MAX_ETM_REGS * num_possible_cpus())
 
+#define OSLOCK_MAGIC		(0xC5ACCE55)
 #define DBGDSCR_MASK		(0x6C30FC3C)
 #define CPMR_ETMCLKEN		(0x8)
+#define TZ_DBG_ETM_FEAT_ID	(0x8)
+#define TZ_DBG_ETM_VER		(0x400000)
 
 
 uint32_t msm_jtag_save_cntr[NR_CPUS];
@@ -38,7 +43,7 @@
 
 struct dbg_ctx {
 	uint8_t		arch;
-	bool		arch_supported;
+	bool		save_restore_enabled;
 	uint8_t		nr_wp;
 	uint8_t		nr_bp;
 	uint8_t		nr_ctx_cmp;
@@ -48,7 +53,7 @@
 
 struct etm_ctx {
 	uint8_t		arch;
-	bool		arch_supported;
+	bool		save_restore_enabled;
 	uint8_t		nr_addr_cmp;
 	uint8_t		nr_cntr;
 	uint8_t		nr_ext_inp;
@@ -1001,16 +1006,23 @@
 	etm_clk_disable();
 }
 
-/* msm_jtag_save_state and msm_jtag_restore_state should be fast
+/**
+ * msm_jtag_save_state - save debug and etm registers
  *
- * These functions will be called either from:
- * 1. per_cpu idle thread context for idle power collapses.
- * 2. per_cpu idle thread context for hotplug/suspend power collapse for
- *    nonboot cpus.
- * 3. suspend thread context for core0.
+ * Debug and etm registers are saved before power collapse if debug
+ * and etm architecture is supported respectively and TZ isn't supporting
+ * the save and restore of debug and etm registers.
  *
- * In all cases we are guaranteed to be running on the same cpu for the
- * entire duration.
+ * CONTEXT:
+ * Called with preemption off and interrupts locked from:
+ * 1. per_cpu idle thread context for idle power collapses
+ * or
+ * 2. per_cpu idle thread context for hotplug/suspend power collapse
+ *    for nonboot cpus
+ * or
+ * 3. suspend thread context for suspend power collapse for core0
+ *
+ * In all cases we will run on the same cpu for the entire duration.
  */
 void msm_jtag_save_state(void)
 {
@@ -1022,12 +1034,31 @@
 	/* ensure counter is updated before moving forward */
 	mb();
 
-	if (dbg.arch_supported)
+	if (dbg.save_restore_enabled)
 		dbg_save_state(cpu);
-	if (etm.arch_supported)
+	if (etm.save_restore_enabled)
 		etm_save_state(cpu);
 }
+EXPORT_SYMBOL(msm_jtag_save_state);
 
+/**
+ * msm_jtag_restore_state - restore debug and etm registers
+ *
+ * Debug and etm registers are restored after power collapse if debug
+ * and etm architecture is supported respectively and TZ isn't supporting
+ * the save and restore of debug and etm registers.
+ *
+ * CONTEXT:
+ * Called with preemption off and interrupts locked from:
+ * 1. per_cpu idle thread context for idle power collapses
+ * or
+ * 2. per_cpu idle thread context for hotplug/suspend power collapse
+ *    for nonboot cpus
+ * or
+ * 3. suspend thread context for suspend power collapse for core0
+ *
+ * In all cases we will run on the same cpu for the entire duration.
+ */
 void msm_jtag_restore_state(void)
 {
 	int cpu;
@@ -1038,11 +1069,12 @@
 	/* ensure counter is updated before moving forward */
 	mb();
 
-	if (dbg.arch_supported)
+	if (dbg.save_restore_enabled)
 		dbg_restore_state(cpu);
-	if (etm.arch_supported)
+	if (etm.save_restore_enabled)
 		etm_restore_state(cpu);
 }
+EXPORT_SYMBOL(msm_jtag_restore_state);
 
 static int __init msm_jtag_dbg_init(void)
 {
@@ -1052,17 +1084,25 @@
 	/* This will run on core0 so use it to populate parameters */
 
 	/* Populate dbg_ctx data */
+
 	dbgdidr = dbg_read(DBGDIDR);
 	dbg.arch = BMVAL(dbgdidr, 16, 19);
-	dbg.arch_supported = dbg_arch_supported(dbg.arch);
-	if (!dbg.arch_supported) {
-		pr_info("dbg arch %u not supported\n", dbg.arch);
-		goto dbg_out;
-	}
 	dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23) + 1;
 	dbg.nr_bp = BMVAL(dbgdidr, 24, 27) + 1;
 	dbg.nr_wp = BMVAL(dbgdidr, 28, 31) + 1;
 
+	if (dbg_arch_supported(dbg.arch)) {
+		if (scm_get_feat_version(TZ_DBG_ETM_FEAT_ID) < TZ_DBG_ETM_VER) {
+			dbg.save_restore_enabled = true;
+		} else {
+			pr_info("dbg save-restore supported by TZ\n");
+			goto dbg_out;
+		}
+	} else {
+		pr_info("dbg arch %u not supported\n", dbg.arch);
+		goto dbg_out;
+	}
+
 	/* Allocate dbg state save space */
 	dbg.state = kzalloc(MAX_DBG_STATE_SIZE * sizeof(uint32_t), GFP_KERNEL);
 	if (!dbg.state) {
@@ -1090,13 +1130,10 @@
 	isb();
 
 	/* Populate etm_ctx data */
+
 	etmidr = etm_read(ETMIDR);
 	etm.arch = BMVAL(etmidr, 4, 11);
-	etm.arch_supported = etm_arch_supported(etm.arch);
-	if (!etm.arch_supported) {
-		pr_info("etm arch %u not supported\n", etm.arch);
-		goto etm_out;
-	}
+
 	etmccr = etm_read(ETMCCR);
 	etm.nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
 	etm.nr_cntr = BMVAL(etmccr, 13, 15);
@@ -1104,6 +1141,18 @@
 	etm.nr_ext_out = BMVAL(etmccr, 20, 22);
 	etm.nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
 
+	if (etm_arch_supported(etm.arch)) {
+		if (scm_get_feat_version(TZ_DBG_ETM_FEAT_ID) < TZ_DBG_ETM_VER) {
+			etm.save_restore_enabled = true;
+		} else {
+			pr_info("etm save-restore supported by TZ\n");
+			goto etm_out;
+		}
+	} else {
+		pr_info("etm arch %u not supported\n", etm.arch);
+		goto etm_out;
+	}
+
 	/* Vote for ETM power/clock disable */
 	etm_clk_disable();
 
@@ -1114,6 +1163,7 @@
 		goto etm_err;
 	}
 etm_out:
+	etm_clk_disable();
 	return 0;
 etm_err:
 	return ret;
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 5eccf06..7775740 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -31,12 +31,10 @@
 
 #define SCM_Q6_NMI_CMD                  0x1
 #define MODULE_NAME			"lpass_8960"
-#define Q6SS_SOFT_INTR_WAKEUP		0x28800024
 
 /* Subsystem restart: QDSP6 data, functions */
 static void lpass_fatal_fn(struct work_struct *);
 static DECLARE_WORK(lpass_fatal_work, lpass_fatal_fn);
-void __iomem *q6_wakeup_intr;
 struct lpass_ssr {
 	void *lpass_ramdump_dev;
 } lpass_ssr;
@@ -118,11 +116,6 @@
 	scm_call(SCM_SVC_UTIL, SCM_Q6_NMI_CMD,
 	&cmd, sizeof(cmd), NULL, 0);
 
-	/* Wakeup the Q6 */
-	if (q6_wakeup_intr)
-		writel_relaxed(0x01, q6_wakeup_intr);
-	mb();
-
 	/* Q6 requires worstcase 100ms to dump caches etc.*/
 	mdelay(100);
 	pr_debug("%s: Q6 NMI was sent.\n", __func__);
@@ -212,9 +205,6 @@
 				__func__, ret);
 		goto out;
 	}
-	q6_wakeup_intr = ioremap_nocache(Q6SS_SOFT_INTR_WAKEUP, 8);
-	if (!q6_wakeup_intr)
-		pr_err("%s: Unable to request q6 wakeup interrupt\n", __func__);
 
 	lpass_ssr_8960.lpass_ramdump_dev = create_ramdump_device("lpass");
 
@@ -230,7 +220,6 @@
 		ret = PTR_ERR(ssr_notif_hdle);
 		pr_err("%s: subsys_register_notifier for Riva: err = %d\n",
 			__func__, ret);
-		iounmap(q6_wakeup_intr);
 		free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
 		goto out;
 	}
@@ -242,7 +231,6 @@
 		pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
 			__func__, ret);
 		subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
-		iounmap(q6_wakeup_intr);
 		free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
 		goto out;
 	}
@@ -256,7 +244,6 @@
 {
 	subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
 	subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
-	iounmap(q6_wakeup_intr);
 	free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
 }
 
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 04c29cc..7fccf2e 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -139,11 +139,14 @@
 {
 	int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
 
+	if (!mdm_drv->mdm_ready)
+		return;
+
 	mdm_drv->ops->status_cb(mdm_drv, value);
 
 	pr_debug("%s: status:%d\n", __func__, value);
 
-	if ((value == 0) && mdm_drv->mdm_ready) {
+	if ((value == 0)) {
 		pr_info("%s: unexpected reset external modem\n", __func__);
 		subsystem_restart(EXTERNAL_MODEM);
 	} else if (value == 1) {
@@ -505,13 +508,8 @@
 
 void mdm_common_modem_shutdown(struct platform_device *pdev)
 {
-	pr_debug("%s: setting AP2MDM_STATUS low for a graceful restart\n",
-		__func__);
-
 	mdm_disable_irqs();
 
-	gpio_set_value(mdm_drv->ap2mdm_status_gpio, 0);
-
 	if (mdm_drv->ap2mdm_wakeup_gpio > 0)
 		gpio_set_value(mdm_drv->ap2mdm_wakeup_gpio, 1);
 
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index 7345a89..7df1c3a 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -93,14 +93,6 @@
 {
 	void __iomem *q6_fw_wdog_addr;
 	void __iomem *q6_sw_wdog_addr;
-	int smsm_notif_unregistered = 0;
-
-	if (!(smsm_get_state(SMSM_MODEM_STATE) & SMSM_RESET)) {
-		smsm_state_cb_deregister(SMSM_MODEM_STATE, SMSM_RESET,
-			smsm_state_cb, 0);
-		smsm_notif_unregistered = 1;
-		smsm_reset_modem(SMSM_RESET);
-	}
 
 	/*
 	 * Disable the modem watchdog since it keeps running even after the
@@ -127,10 +119,6 @@
 	disable_irq_nosync(Q6FW_WDOG_EXPIRED_IRQ);
 	disable_irq_nosync(Q6SW_WDOG_EXPIRED_IRQ);
 
-	if (smsm_notif_unregistered)
-		smsm_state_cb_register(SMSM_MODEM_STATE, SMSM_RESET,
-			smsm_state_cb, 0);
-
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/msm_dcvs_idle.c b/arch/arm/mach-msm/msm_dcvs_idle.c
new file mode 100644
index 0000000..59f2742
--- /dev/null
+++ b/arch/arm/mach-msm/msm_dcvs_idle.c
@@ -0,0 +1,170 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/cpu_pm.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos_params.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <mach/msm_dcvs.h>
+
+struct cpu_idle_info {
+	int cpu;
+	int enabled;
+	int handle;
+	struct msm_dcvs_idle dcvs_notifier;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_idle_info, cpu_idle_info);
+static DEFINE_PER_CPU_SHARED_ALIGNED(u64, iowait_on_cpu);
+static char core_name[NR_CPUS][10];
+static struct pm_qos_request_list qos_req;
+static uint32_t latency;
+
+static int msm_dcvs_idle_notifier(struct msm_dcvs_idle *self,
+		enum msm_core_control_event event)
+{
+	struct cpu_idle_info *info = container_of(self,
+				struct cpu_idle_info, dcvs_notifier);
+
+	switch (event) {
+	case MSM_DCVS_ENABLE_IDLE_PULSE:
+		info->enabled = true;
+		break;
+
+	case MSM_DCVS_DISABLE_IDLE_PULSE:
+		info->enabled = false;
+		break;
+
+	case MSM_DCVS_ENABLE_HIGH_LATENCY_MODES:
+		pm_qos_update_request(&qos_req, PM_QOS_DEFAULT_VALUE);
+		break;
+
+	case MSM_DCVS_DISABLE_HIGH_LATENCY_MODES:
+		pm_qos_update_request(&qos_req, latency);
+		break;
+	}
+
+	return 0;
+}
+
+static int msm_cpuidle_notifier(struct notifier_block *self, unsigned long cmd,
+		void *v)
+{
+	struct cpu_idle_info *info =
+		&per_cpu(cpu_idle_info, smp_processor_id());
+	u64 io_wait_us = 0;
+	u64 prev_io_wait_us = 0;
+	u64 last_update_time = 0;
+	u64 val = 0;
+	uint32_t iowaited = 0;
+
+	if (!info->enabled)
+		return NOTIFY_OK;
+
+	switch (cmd) {
+	case CPU_PM_ENTER:
+		val = get_cpu_iowait_time_us(smp_processor_id(),
+					&last_update_time);
+		/* val could be -1 when NOHZ is not enabled */
+		if (val == (u64)-1)
+			val = 0;
+		per_cpu(iowait_on_cpu, smp_processor_id()) = val;
+		msm_dcvs_idle(info->handle, MSM_DCVS_IDLE_ENTER, 0);
+		break;
+
+	case CPU_PM_ENTER_FAILED:
+	case CPU_PM_EXIT:
+		prev_io_wait_us = per_cpu(iowait_on_cpu, smp_processor_id());
+		val = get_cpu_iowait_time_us(smp_processor_id(),
+				&last_update_time);
+		if (val == (u64)-1)
+			val = 0;
+		io_wait_us = val;
+		iowaited = (io_wait_us - prev_io_wait_us);
+		msm_dcvs_idle(info->handle, MSM_DCVS_IDLE_EXIT, iowaited);
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block idle_nb = {
+	.notifier_call = msm_cpuidle_notifier,
+};
+
+static int msm_dcvs_idle_probe(struct platform_device *pdev)
+{
+	int cpu;
+	struct cpu_idle_info *info = NULL;
+	struct msm_dcvs_idle *inotify = NULL;
+
+	for_each_possible_cpu(cpu) {
+		info = &per_cpu(cpu_idle_info, cpu);
+		info->cpu = cpu;
+		inotify = &info->dcvs_notifier;
+		snprintf(core_name[cpu], 10, "cpu%d", cpu);
+		inotify->core_name = core_name[cpu];
+		inotify->enable = msm_dcvs_idle_notifier;
+		info->handle = msm_dcvs_idle_source_register(inotify);
+		BUG_ON(info->handle < 0);
+	}
+
+	latency = *((uint32_t *)pdev->dev.platform_data);
+	pm_qos_add_request(&qos_req, PM_QOS_CPU_DMA_LATENCY,
+				PM_QOS_DEFAULT_VALUE);
+
+	return cpu_pm_register_notifier(&idle_nb);
+}
+
+static int msm_dcvs_idle_remove(struct platform_device *pdev)
+{
+	int ret = 0;
+	int rc = 0;
+	int cpu = 0;
+	struct msm_dcvs_idle *inotify = NULL;
+	struct cpu_idle_info *info = NULL;
+
+	rc = cpu_pm_unregister_notifier(&idle_nb);
+
+	for_each_possible_cpu(cpu) {
+		info = &per_cpu(cpu_idle_info, cpu);
+		inotify = &info->dcvs_notifier;
+		ret = msm_dcvs_idle_source_unregister(inotify);
+		if (ret) {
+			rc = -EFAULT;
+			pr_err("Error de-registering core %d idle notifier.\n",
+					cpu);
+		}
+	}
+
+	return rc;
+}
+
+static struct platform_driver idle_pdrv = {
+	.probe = msm_dcvs_idle_probe,
+	.remove = __devexit_p(msm_dcvs_idle_remove),
+	.driver = {
+		.name  = "msm_cpu_idle",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int msm_dcvs_idle_init(void)
+{
+	return platform_driver_register(&idle_pdrv);
+}
+late_initcall(msm_dcvs_idle_init);
diff --git a/arch/arm/mach-msm/msm_watchdog.c b/arch/arm/mach-msm/msm_watchdog.c
index 28b5995..994dca6 100644
--- a/arch/arm/mach-msm/msm_watchdog.c
+++ b/arch/arm/mach-msm/msm_watchdog.c
@@ -47,6 +47,7 @@
 static unsigned long delay_time;
 static unsigned long bark_time;
 static unsigned long long last_pet;
+static bool has_vic;
 
 /*
  * On the kernel command line specify
@@ -161,9 +162,14 @@
 		if (!old_val) {
 			__raw_writel(0, msm_tmr0_base + WDT0_EN);
 			mb();
-			disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
-			free_percpu_irq(WDT0_ACCSCSSNBARK_INT, percpu_pdata);
-			free_percpu(percpu_pdata);
+			if (has_vic) {
+				free_irq(WDT0_ACCSCSSNBARK_INT, 0);
+			} else {
+				disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
+				free_percpu_irq(WDT0_ACCSCSSNBARK_INT,
+					percpu_pdata);
+				free_percpu(percpu_pdata);
+			}
 			enable = 0;
 			atomic_notifier_chain_unregister(&panic_notifier_list,
 			       &panic_blk);
@@ -221,9 +227,13 @@
 	if (enable) {
 		__raw_writel(0, msm_tmr0_base + WDT0_EN);
 		mb();
-		disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
-		free_percpu_irq(WDT0_ACCSCSSNBARK_INT, percpu_pdata);
-		free_percpu(percpu_pdata);
+		if (has_vic) {
+			free_irq(WDT0_ACCSCSSNBARK_INT, 0);
+		} else {
+			disable_percpu_irq(WDT0_ACCSCSSNBARK_INT);
+			free_percpu_irq(WDT0_ACCSCSSNBARK_INT, percpu_pdata);
+			free_percpu(percpu_pdata);
+		}
 		enable = 0;
 		/* In case we got suspended mid-exit */
 		__raw_writel(0, msm_tmr0_base + WDT0_EN);
@@ -338,26 +348,34 @@
 		appsbark = 1;
 
 	bark_time = pdata->bark_time;
+	has_vic = pdata->has_vic;
 
 	msm_tmr0_base = msm_timer_get_timer0_base();
 
-	percpu_pdata = alloc_percpu(struct msm_watchdog_pdata *);
-	if (!percpu_pdata) {
-		pr_err("%s: memory allocation failed for percpu data\n",
-				__func__);
-		return -ENOMEM;
-	}
+	if (has_vic) {
+		ret = request_irq(WDT0_ACCSCSSNBARK_INT, wdog_bark_handler, 0,
+				  "apps_wdog_bark", NULL);
+		if (ret)
+			return ret;
+	} else {
+		percpu_pdata = alloc_percpu(struct msm_watchdog_pdata *);
+		if (!percpu_pdata) {
+			pr_err("%s: memory allocation failed for percpu data\n",
+					__func__);
+			return -ENOMEM;
+		}
 
-	*__this_cpu_ptr(percpu_pdata) = pdata;
-	/* Must request irq before sending scm command */
-	ret = request_percpu_irq(WDT0_ACCSCSSNBARK_INT, wdog_bark_handler,
-			  "apps_wdog_bark", percpu_pdata);
-	if (ret) {
-		free_percpu(percpu_pdata);
-		return ret;
-	}
+		*__this_cpu_ptr(percpu_pdata) = pdata;
+		/* Must request irq before sending scm command */
+		ret = request_percpu_irq(WDT0_ACCSCSSNBARK_INT,
+			wdog_bark_handler, "apps_wdog_bark", percpu_pdata);
+		if (ret) {
+			free_percpu(percpu_pdata);
+			return ret;
+		}
 
-	enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, IRQ_TYPE_EDGE_RISING);
+		enable_percpu_irq(WDT0_ACCSCSSNBARK_INT, IRQ_TYPE_EDGE_RISING);
+	}
 
 	/*
 	 * This is only temporary till SBLs turn on the XPUs
diff --git a/arch/arm/mach-msm/msm_watchdog.h b/arch/arm/mach-msm/msm_watchdog.h
index 33e9e0c..7156dfc 100644
--- a/arch/arm/mach-msm/msm_watchdog.h
+++ b/arch/arm/mach-msm/msm_watchdog.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,7 @@
 	unsigned int bark_time;
 	bool has_secure;
 	bool needs_expired_enable;
+	bool has_vic;
 };
 
 #ifdef CONFIG_MSM_WATCHDOG
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 936fd6b..86776d3 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -21,6 +21,7 @@
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/string.h>
+#include <linux/clk.h>
 
 #include <mach/msm_xo.h>
 #include <mach/rpm.h>
@@ -232,6 +233,9 @@
 {
 	int ret;
 	struct msm_xo *xo = xo_voter->xo;
+	int is_d0 = xo == &msm_xo_sources[MSM_XO_TCXO_D0];
+	int needs_workaround = cpu_is_msm8960() || cpu_is_apq8064() ||
+			       cpu_is_msm8930() || cpu_is_msm9615();
 
 	if (xo_voter->mode == mode)
 		return 0;
@@ -244,6 +248,20 @@
 		xo->votes[mode]--;
 		goto out;
 	}
+	/* TODO: Remove once RPM separates the concept of D0 and CXO */
+	if (is_d0 && needs_workaround) {
+		static struct clk *xo_clk;
+
+		if (!xo_clk) {
+			xo_clk = clk_get_sys("msm_xo", "xo");
+			BUG_ON(IS_ERR(xo_clk));
+		}
+		/* Ignore transitions from pin to on or vice versa */
+		if (mode && xo_voter->mode == MSM_XO_MODE_OFF)
+			clk_enable(xo_clk);
+		else if (!mode)
+			clk_disable(xo_clk);
+	}
 	xo_voter->mode = mode;
 out:
 	return ret;
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
index 3c46d0f..82aeb16 100644
--- a/arch/arm/mach-msm/platsmp-8625.c
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -17,6 +17,7 @@
 #include <linux/jiffies.h>
 #include <linux/smp.h>
 #include <linux/io.h>
+#include <linux/interrupt.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/gic.h>
@@ -59,6 +60,78 @@
 }
 
 static DEFINE_SPINLOCK(boot_lock);
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+
+/*
+ * MP_CORE_IPC will be used to generate interrupt and can be used by either
+ * of core.
+ * To bring core1 out of GDFS we need to raise the SPI using the MP_CORE_IPC.
+ */
+static void raise_clear_spi(unsigned int cpu, bool set)
+{
+	int value;
+
+	value = __raw_readl(MSM_CSR_BASE + 0x54);
+	if (set)
+		__raw_writel(value | BIT(cpu), MSM_CSR_BASE + 0x54);
+	else
+		__raw_writel(value & ~BIT(cpu), MSM_CSR_BASE + 0x54);
+	mb();
+}
+
+/*
+ * Configure the GIC after we come out of power collapse.
+ * This function will configure some of the GIC registers so as to prepare the
+ * core1 to receive an SPI(ACSR_MP_CORE_IPC1, (32 + 8)), which will bring
+ * core1 out of GDFS.
+ */
+static void core1_gic_configure_and_raise(void)
+{
+	unsigned int value = 0;
+
+	raw_spin_lock(&irq_controller_lock);
+
+	value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_ACTIVE_BIT + 0x4);
+	value |= BIT(8);
+	__raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_ACTIVE_BIT + 0x4);
+	mb();
+
+	value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x24);
+	value |= BIT(13);
+	__raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x24);
+	mb();
+
+	value = __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x28);
+	value |= BIT(1);
+	__raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_TARGET + 0x28);
+	mb();
+
+	value =  __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET + 0x4);
+	value |= BIT(8);
+	__raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET + 0x4);
+	mb();
+
+	value =  __raw_readl(MSM_QGIC_DIST_BASE + GIC_DIST_PENDING_SET + 0x4);
+	value |= BIT(8);
+	__raw_writel(value, MSM_QGIC_DIST_BASE + GIC_DIST_PENDING_SET + 0x4);
+	mb();
+
+	raise_clear_spi(1, true);
+	raw_spin_unlock(&irq_controller_lock);
+}
+
+void clear_pending_spi(unsigned int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	struct irq_chip *c = irq_data_get_irq_chip(d);
+
+	/* Clear the IRQ from the ENABLE_SET */
+	c->irq_mask(d);
+	local_irq_disable();
+	gic_clear_spi_pending(irq);
+	c->irq_unmask(d);
+	local_irq_enable();
+}
 
 void __cpuinit platform_secondary_init(unsigned int cpu)
 {
@@ -153,8 +226,16 @@
 	 * Send the secondary CPU a soft interrupt, thereby causing
 	 * the boot monitor to read the system wide flags register,
 	 * and branch to the address found there.
+	 *
+	 * power_collapsed is the flag which will be updated for Powercollapse.
+	 * Once we are out of PC, as Core1 will be in the state of GDFS which
+	 * needs to be brought out by raising an SPI.
 	 */
-	gic_raise_softirq(cpumask_of(cpu), 1);
+
+	if (power_collapsed)
+		core1_gic_configure_and_raise();
+	else
+		gic_raise_softirq(cpumask_of(cpu), 1);
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
@@ -165,6 +246,13 @@
 		udelay(10);
 	}
 
+	/* Now we should clear the pending SPI */
+	if (power_collapsed) {
+		raise_clear_spi(1, false);
+		clear_pending_spi(MSM8625_INT_ACSR_MP_CORE_IPC1);
+		power_collapsed = 0;
+	}
+
 	/*
 	 * now the secondary core is starting up let it run its
 	 * calibrations, then wait for it to finish
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index ad235de..9257f2f 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -49,7 +49,6 @@
 #include "scm-boot.h"
 #include "spm.h"
 #include "timer.h"
-#include "qdss.h"
 #include "pm-boot.h"
 
 /******************************************************************************
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 892472b..4e9cc3c 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -27,6 +27,8 @@
 #define msm_secondary_startup NULL
 #endif
 
+extern int power_collapsed;
+
 enum msm_pm_sleep_mode {
 	MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND,
 	MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 6b026ac..94bc98f 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -80,6 +80,7 @@
 };
 
 static int msm_pm_debug_mask;
+int power_collapsed;
 module_param_named(
 	debug_mask, msm_pm_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
 );
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index 6d36495..083a9f1 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -14,7 +14,9 @@
 endif
 obj-$(CONFIG_MSM_QDSP6_APR) += apr.o apr_tal.o q6core.o dsp_debug.o
 obj-y += audio_acdb.o
+ifndef CONFIG_ARCH_MSM9615
 obj-y += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
 obj-y += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
 obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/
 obj-y += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
+endif
diff --git a/arch/arm/mach-msm/qdss-etb.c b/arch/arm/mach-msm/qdss-etb.c
index 252352c..8b5f8db 100644
--- a/arch/arm/mach-msm/qdss-etb.c
+++ b/arch/arm/mach-msm/qdss-etb.c
@@ -25,7 +25,7 @@
 #include <linux/delay.h>
 #include <linux/mutex.h>
 
-#include "qdss.h"
+#include "qdss-priv.h"
 
 #define etb_writel(etb, val, off)	__raw_writel((val), etb.base + off)
 #define etb_readl(etb, off)		__raw_readl(etb.base + off)
diff --git a/arch/arm/mach-msm/qdss-etm.c b/arch/arm/mach-msm/qdss-etm.c
index 4bc3f495..eeb7519 100644
--- a/arch/arm/mach-msm/qdss-etm.c
+++ b/arch/arm/mach-msm/qdss-etm.c
@@ -29,7 +29,7 @@
 #include <asm/sections.h>
 #include <mach/socinfo.h>
 
-#include "qdss.h"
+#include "qdss-priv.h"
 
 #define etm_writel(etm, cpu, val, off)	\
 			__raw_writel((val), etm.base + (SZ_4K * cpu) + off)
diff --git a/arch/arm/mach-msm/qdss-funnel.c b/arch/arm/mach-msm/qdss-funnel.c
index 3eec560..990295b 100644
--- a/arch/arm/mach-msm/qdss-funnel.c
+++ b/arch/arm/mach-msm/qdss-funnel.c
@@ -19,7 +19,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 
-#include "qdss.h"
+#include "qdss-priv.h"
 
 #define funnel_writel(funnel, id, val, off)	\
 			__raw_writel((val), funnel.base + (SZ_4K * id) + off)
@@ -52,14 +52,13 @@
 struct funnel_ctx {
 	void __iomem	*base;
 	bool		enabled;
+	struct mutex	mutex;
 	struct device	*dev;
 	struct kobject	*kobj;
 	uint32_t	priority;
 };
 
-static struct funnel_ctx funnel = {
-	.priority	= 0xFAC680,
-};
+static struct funnel_ctx funnel;
 
 static void __funnel_enable(uint8_t id, uint32_t port_mask)
 {
@@ -79,10 +78,12 @@
 
 void funnel_enable(uint8_t id, uint32_t port_mask)
 {
+	mutex_lock(&funnel.mutex);
 	__funnel_enable(id, port_mask);
 	funnel.enabled = true;
 	dev_info(funnel.dev, "FUNNEL port mask 0x%lx enabled\n",
 					(unsigned long) port_mask);
+	mutex_unlock(&funnel.mutex);
 }
 
 static void __funnel_disable(uint8_t id, uint32_t port_mask)
@@ -100,10 +101,12 @@
 
 void funnel_disable(uint8_t id, uint32_t port_mask)
 {
+	mutex_lock(&funnel.mutex);
 	__funnel_disable(id, port_mask);
 	funnel.enabled = false;
 	dev_info(funnel.dev, "FUNNEL port mask 0x%lx disabled\n",
 					(unsigned long) port_mask);
+	mutex_unlock(&funnel.mutex);
 }
 
 #define FUNNEL_ATTR(__name)						\
@@ -181,6 +184,8 @@
 
 	funnel.dev = &pdev->dev;
 
+	mutex_init(&funnel.mutex);
+
 	funnel_sysfs_init();
 
 	dev_info(funnel.dev, "FUNNEL initialized\n");
@@ -197,6 +202,7 @@
 	if (funnel.enabled)
 		funnel_disable(0x0, 0xFF);
 	funnel_sysfs_exit();
+	mutex_destroy(&funnel.mutex);
 	iounmap(funnel.base);
 
 	return 0;
diff --git a/arch/arm/mach-msm/qdss.h b/arch/arm/mach-msm/qdss-priv.h
similarity index 87%
rename from arch/arm/mach-msm/qdss.h
rename to arch/arm/mach-msm/qdss-priv.h
index fee0587..b9f3072 100644
--- a/arch/arm/mach-msm/qdss.h
+++ b/arch/arm/mach-msm/qdss-priv.h
@@ -14,6 +14,7 @@
 #define _ARCH_ARM_MACH_MSM_QDSS_H_
 
 #include <linux/bitops.h>
+#include <mach/qdss.h>
 
 /* Coresight management registers (0xF00-0xFCC)
  * 0xFA0 - 0xFA4: Management	registers in PFTv1.0
@@ -51,7 +52,6 @@
 #define PFT_ARCH_V1_1		(0x31)
 
 #define TIMEOUT_US		(100)
-#define OSLOCK_MAGIC		(0xC5ACCE55)
 #define CS_UNLOCK_MAGIC		(0xC5ACCE55)
 
 #define BM(lsb, msb)		((BIT(msb) - BIT(lsb)) + BIT(msb))
@@ -75,15 +75,5 @@
 void funnel_disable(uint8_t id, uint32_t port_mask);
 
 struct kobject *qdss_get_modulekobj(void);
-int qdss_clk_enable(void);
-void qdss_clk_disable(void);
-
-#ifdef CONFIG_MSM_JTAG
-extern void msm_jtag_save_state(void);
-extern void msm_jtag_restore_state(void);
-#else
-static inline void msm_jtag_save_state(void) {}
-static inline void msm_jtag_restore_state(void) {}
-#endif
 
 #endif
diff --git a/arch/arm/mach-msm/qdss-tpiu.c b/arch/arm/mach-msm/qdss-tpiu.c
index 409bf2c..4481a0a 100644
--- a/arch/arm/mach-msm/qdss-tpiu.c
+++ b/arch/arm/mach-msm/qdss-tpiu.c
@@ -18,7 +18,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 
-#include "qdss.h"
+#include "qdss-priv.h"
 
 #define tpiu_writel(tpiu, val, off)	__raw_writel((val), tpiu.base + off)
 #define tpiu_readl(tpiu, off)		__raw_readl(tpiu.base + off)
diff --git a/arch/arm/mach-msm/qdss.c b/arch/arm/mach-msm/qdss.c
index ab28c82..80ec65a 100644
--- a/arch/arm/mach-msm/qdss.c
+++ b/arch/arm/mach-msm/qdss.c
@@ -18,10 +18,11 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <mach/rpm.h>
 
 #include "rpm_resources.h"
-#include "qdss.h"
+#include "qdss-priv.h"
 
 enum {
 	QDSS_CLK_OFF,
@@ -32,6 +33,8 @@
 struct qdss_ctx {
 	struct kobject	*modulekobj;
 	uint8_t		max_clk;
+	uint8_t		clk_count;
+	struct mutex	clk_mutex;
 };
 
 static struct qdss_ctx qdss;
@@ -42,35 +45,71 @@
 	return qdss.modulekobj;
 }
 
+/**
+ * qdss_clk_enable - enable qdss clocks
+ *
+ * Enables qdss clocks via RPM if they aren't already enabled, otherwise
+ * increments the reference count.
+ *
+ * CONTEXT:
+ * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
+ *
+ * RETURNS:
+ * 0 on success, non-zero on failure
+ */
 int qdss_clk_enable(void)
 {
 	int ret;
-
 	struct msm_rpm_iv_pair iv;
-	iv.id = MSM_RPM_ID_QDSS_CLK;
-	if (qdss.max_clk)
-		iv.value = QDSS_CLK_ON_HSDBG;
-	else
-		iv.value = QDSS_CLK_ON_DBG;
-	ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
-	if (WARN(ret, "qdss clks not enabled (%d)\n", ret))
-		goto err_clk;
 
+	mutex_lock(&qdss.clk_mutex);
+	if (qdss.clk_count == 0) {
+		iv.id = MSM_RPM_ID_QDSS_CLK;
+		if (qdss.max_clk)
+			iv.value = QDSS_CLK_ON_HSDBG;
+		else
+			iv.value = QDSS_CLK_ON_DBG;
+		ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
+		if (WARN(ret, "qdss clks not enabled (%d)\n", ret))
+			goto err_clk;
+	}
+	qdss.clk_count++;
+	mutex_unlock(&qdss.clk_mutex);
 	return 0;
 err_clk:
+	mutex_unlock(&qdss.clk_mutex);
 	return ret;
 }
+EXPORT_SYMBOL(qdss_clk_enable);
 
+/**
+ * qdss_clk_disable - disable qdss clocks
+ *
+ * Disables qdss clocks via RPM if the reference count is one, otherwise
+ * decrements the reference count.
+ *
+ * CONTEXT:
+ * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
+ */
 void qdss_clk_disable(void)
 {
 	int ret;
 	struct msm_rpm_iv_pair iv;
 
-	iv.id = MSM_RPM_ID_QDSS_CLK;
-	iv.value = QDSS_CLK_OFF;
-	ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
-	WARN(ret, "qdss clks not disabled (%d)\n", ret);
+	mutex_lock(&qdss.clk_mutex);
+	if (WARN(qdss.clk_count == 0, "qdss clks are unbalanced\n"))
+		goto out;
+	if (qdss.clk_count == 1) {
+		iv.id = MSM_RPM_ID_QDSS_CLK;
+		iv.value = QDSS_CLK_OFF;
+		ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
+		WARN(ret, "qdss clks not disabled (%d)\n", ret);
+	}
+	qdss.clk_count--;
+out:
+	mutex_unlock(&qdss.clk_mutex);
 }
+EXPORT_SYMBOL(qdss_clk_disable);
 
 #define QDSS_ATTR(name)						\
 static struct kobj_attribute name##_attr =				\
@@ -128,6 +167,8 @@
 {
 	int ret;
 
+	mutex_init(&qdss.clk_mutex);
+
 	ret = qdss_sysfs_init();
 	if (ret)
 		goto err_sysfs;
@@ -155,6 +196,7 @@
 err_etb:
 	qdss_sysfs_exit();
 err_sysfs:
+	mutex_destroy(&qdss.clk_mutex);
 	pr_err("QDSS init failed\n");
 	return ret;
 }
@@ -167,6 +209,7 @@
 	funnel_exit();
 	tpiu_exit();
 	etb_exit();
+	mutex_destroy(&qdss.clk_mutex);
 }
 module_exit(qdss_exit);
 
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
index cdb0cbe..e664414 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-msm/scm.c
@@ -414,6 +414,19 @@
 }
 EXPORT_SYMBOL(scm_is_call_available);
 
+#define GET_FEAT_VERSION_CMD	3
+int scm_get_feat_version(u32 feat)
+{
+	if (scm_is_call_available(SCM_SVC_INFO, GET_FEAT_VERSION_CMD)) {
+		u32 version;
+		if (!scm_call(SCM_SVC_INFO, GET_FEAT_VERSION_CMD, &feat,
+				sizeof(feat), &version, sizeof(version)))
+			return version;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(scm_get_feat_version);
+
 static int scm_init(void)
 {
 	u32 ctr;
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index c237978..a1c044e 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -32,6 +32,7 @@
 #include <linux/remote_spinlock.h>
 #include <linux/uaccess.h>
 #include <linux/kfifo.h>
+#include <linux/wakelock.h>
 #include <mach/msm_smd.h>
 #include <mach/msm_iomap.h>
 #include <mach/system.h>
@@ -82,7 +83,10 @@
 };
 
 static struct smsm_shared_info smsm_info;
-struct kfifo smsm_snapshot_fifo;
+static struct kfifo smsm_snapshot_fifo;
+static struct wake_lock smsm_snapshot_wakelock;
+static int smsm_snapshot_count;
+static DEFINE_SPINLOCK(smsm_snapshot_count_lock);
 
 struct smsm_size_info_type {
 	uint32_t num_hosts;
@@ -1931,42 +1935,77 @@
 
 int smd_read(smd_channel_t *ch, void *data, int len)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->read(ch, data, len, 0);
 }
 EXPORT_SYMBOL(smd_read);
 
 int smd_read_user_buffer(smd_channel_t *ch, void *data, int len)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->read(ch, data, len, 1);
 }
 EXPORT_SYMBOL(smd_read_user_buffer);
 
 int smd_read_from_cb(smd_channel_t *ch, void *data, int len)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->read_from_cb(ch, data, len, 0);
 }
 EXPORT_SYMBOL(smd_read_from_cb);
 
 int smd_write(smd_channel_t *ch, const void *data, int len)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, 0);
 }
 EXPORT_SYMBOL(smd_write);
 
 int smd_write_user_buffer(smd_channel_t *ch, const void *data, int len)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, 1);
 }
 EXPORT_SYMBOL(smd_write_user_buffer);
 
 int smd_read_avail(smd_channel_t *ch)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->read_avail(ch);
 }
 EXPORT_SYMBOL(smd_read_avail);
 
 int smd_write_avail(smd_channel_t *ch)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->write_avail(ch);
 }
 EXPORT_SYMBOL(smd_write_avail);
@@ -1997,12 +2036,22 @@
 
 int smd_cur_packet_size(smd_channel_t *ch)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return ch->current_packet;
 }
 EXPORT_SYMBOL(smd_cur_packet_size);
 
 int smd_tiocmget(smd_channel_t *ch)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	return  (ch->recv->fDSR ? TIOCM_DSR : 0) |
 		(ch->recv->fCTS ? TIOCM_CTS : 0) |
 		(ch->recv->fCD ? TIOCM_CD : 0) |
@@ -2016,6 +2065,11 @@
 int
 smd_tiocmset_from_cb(smd_channel_t *ch, unsigned int set, unsigned int clear)
 {
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	if (set & TIOCM_DTR)
 		ch->send->fDSR = 1;
 
@@ -2040,6 +2094,11 @@
 {
 	unsigned long flags;
 
+	if (!ch) {
+		pr_err("%s: Invalid channel specified\n", __func__);
+		return -ENODEV;
+	}
+
 	spin_lock_irqsave(&smd_lock, flags);
 	smd_tiocmset_from_cb(ch, set, clear);
 	spin_unlock_irqrestore(&smd_lock, flags);
@@ -2209,6 +2268,8 @@
 		pr_err("%s: SMSM state fifo alloc failed %d\n", __func__, i);
 		return i;
 	}
+	wake_lock_init(&smsm_snapshot_wakelock, WAKE_LOCK_SUSPEND,
+			"smsm_snapshot");
 
 	if (!smsm_info.state) {
 		smsm_info.state = smem_alloc2(ID_SHARED_STATE,
@@ -2283,6 +2344,7 @@
 {
 	int n;
 	uint32_t new_state;
+	unsigned long flags;
 	int ret;
 
 	ret = kfifo_avail(&smsm_snapshot_fifo);
@@ -2301,6 +2363,14 @@
 			return;
 		}
 	}
+
+	spin_lock_irqsave(&smsm_snapshot_count_lock, flags);
+	if (smsm_snapshot_count == 0) {
+		SMx_POWER_INFO("SMSM snapshot wake lock\n");
+		wake_lock(&smsm_snapshot_wakelock);
+	}
+	++smsm_snapshot_count;
+	spin_unlock_irqrestore(&smsm_snapshot_count_lock, flags);
 	schedule_work(&smsm_cb_work);
 }
 
@@ -2523,6 +2593,7 @@
 	uint32_t new_state;
 	uint32_t state_changes;
 	int ret;
+	unsigned long flags;
 	int snapshot_size = SMSM_NUM_ENTRIES * sizeof(uint32_t);
 
 	if (!smd_initialized)
@@ -2559,6 +2630,18 @@
 			}
 		}
 		mutex_unlock(&smsm_lock);
+
+		spin_lock_irqsave(&smsm_snapshot_count_lock, flags);
+		if (smsm_snapshot_count) {
+			--smsm_snapshot_count;
+			if (smsm_snapshot_count == 0) {
+				SMx_POWER_INFO("SMSM snapshot wake unlock\n");
+				wake_unlock(&smsm_snapshot_wakelock);
+			}
+		} else {
+			pr_err("%s: invalid snapshot count\n", __func__);
+		}
+		spin_unlock_irqrestore(&smsm_snapshot_count_lock, flags);
 	}
 }
 
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 542d224..9ef4028 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -40,7 +40,7 @@
 #ifdef CONFIG_ARCH_FSM9XXX
 #define NUM_SMD_PKT_PORTS 4
 #else
-#define NUM_SMD_PKT_PORTS 12
+#define NUM_SMD_PKT_PORTS 13
 #endif
 
 #define LOOPBACK_INX (NUM_SMD_PKT_PORTS - 1)
@@ -547,6 +547,7 @@
 	"smd22",
 	"smd_sns_dsps",
 	"apr_apps2",
+	"smdcntl8",
 	"smd_pkt_loopback",
 };
 
@@ -562,6 +563,7 @@
 	"DATA22",
 	"SENSOR",
 	"apr_apps2",
+	"DATA40_CNTL",
 	"LOOPBACK",
 };
 
@@ -578,6 +580,7 @@
 	SMD_APPS_DSPS,
 	SMD_APPS_QDSP,
 	SMD_APPS_MODEM,
+	SMD_APPS_MODEM,
 };
 #endif
 
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 78a6203..04dc392 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -577,7 +577,8 @@
 		n_restart_orders = ARRAY_SIZE(orders_8x60_all);
 	}
 
-	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615()) {
+	if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
+			cpu_is_apq8064()) {
 		restart_orders = restart_orders_8960;
 		n_restart_orders = ARRAY_SIZE(restart_orders_8960);
 	}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 2dfde6f..ae7bc32 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1123,8 +1123,13 @@
 	}
 	msm_sched_clock_init();
 
-	__raw_writel(1, msm_clocks[MSM_CLOCK_DGT].regbase + TIMER_ENABLE);
-	set_delay_fn(read_current_timer_delay_loop);
+#ifdef ARCH_HAS_READ_CURRENT_TIMER
+	if (is_smp()) {
+		__raw_writel(1,
+			msm_clocks[MSM_CLOCK_DGT].regbase + TIMER_ENABLE);
+		set_delay_fn(read_current_timer_delay_loop);
+	}
+#endif
 }
 
 #ifdef CONFIG_SMP
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index edede47..cde8031 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1141,3 +1141,4 @@
 msm7627a_qrd3		MACH_MSM7627A_QRD3	MSM7627A_QRD3		4005
 msm8625_surf		MACH_MSM8625_SURF	MSM8625_SURF		4037
 msm8625_evb		MACH_MSM8625_EVB	MSM8625_EVB		4042
+msm8625_qrd7		MACH_MSM8625_QRD7	MSM8625_QRD7		4095
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 332922e..8f51e2d 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -48,6 +48,7 @@
 static int hcismd_set_enable(const char *val, struct kernel_param *kp);
 module_param_call(hcismd_set, hcismd_set_enable, NULL, &hcismd_set, 0644);
 
+static void hci_dev_smd_open(struct work_struct *worker);
 static void hci_dev_restart(struct work_struct *worker);
 
 struct hci_smd_data {
@@ -315,6 +316,8 @@
 	struct hci_dev *hdev = hs.hdev;
 	struct hci_smd_data *hsmd = &hs;
 	struct work_struct *reset_worker;
+	struct work_struct *open_worker;
+
 	int len = 0;
 
 	if (!hdev) {
@@ -334,6 +337,13 @@
 	case SMD_EVENT_OPEN:
 		BT_INFO("opening HCI-SMD channel :%s", EVENT_CHANNEL);
 		hci_smd_open(hdev);
+		open_worker = kzalloc(sizeof(*open_worker), GFP_ATOMIC);
+		if (!open_worker) {
+			BT_ERR("Out of memory");
+			break;
+		}
+		INIT_WORK(open_worker, hci_dev_smd_open);
+		schedule_work(open_worker);
 		break;
 	case SMD_EVENT_CLOSE:
 		BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL);
@@ -384,9 +394,24 @@
 
 }
 
-static int hci_smd_register_dev(struct hci_smd_data *hsmd)
+static int hci_smd_hci_register_dev(struct hci_smd_data *hsmd)
 {
-	static struct hci_dev *hdev;
+	struct hci_dev *hdev;
+
+	hdev = hsmd->hdev;
+
+	if (hci_register_dev(hdev) < 0) {
+		BT_ERR("Can't register HCI device");
+		hci_free_dev(hdev);
+		hsmd->hdev = NULL;
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int hci_smd_register_smd(struct hci_smd_data *hsmd)
+{
+	struct hci_dev *hdev;
 	int rc;
 
 	/* Initialize and register HCI device */
@@ -421,7 +446,7 @@
 	if (rc < 0) {
 		BT_ERR("Cannot open the command channel");
 		hci_free_dev(hdev);
-		hdev = NULL;
+		hsmd->hdev = NULL;
 		return -ENODEV;
 	}
 
@@ -430,18 +455,13 @@
 	if (rc < 0) {
 		BT_ERR("Failed to open the Data channel");
 		hci_free_dev(hdev);
-		hdev = NULL;
+		hsmd->hdev = NULL;
 		return -ENODEV;
 	}
 
 	/* Disable the read interrupts on the channel */
 	smd_disable_read_intr(hsmd->event_channel);
 	smd_disable_read_intr(hsmd->data_channel);
-	if (hci_register_dev(hdev) < 0) {
-		BT_ERR("Can't register HCI device");
-		hci_free_dev(hdev);
-		return -ENODEV;
-	}
 	return 0;
 }
 
@@ -478,7 +498,15 @@
 {
 	mutex_lock(&hci_smd_enable);
 	hci_smd_deregister_dev(&hs);
-	hci_smd_register_dev(&hs);
+	hci_smd_register_smd(&hs);
+	mutex_unlock(&hci_smd_enable);
+	kfree(worker);
+}
+
+static void hci_dev_smd_open(struct work_struct *worker)
+{
+	mutex_lock(&hci_smd_enable);
+	hci_smd_hci_register_dev(&hs);
 	mutex_unlock(&hci_smd_enable);
 	kfree(worker);
 }
@@ -497,7 +525,7 @@
 	switch (hcismd_set) {
 
 	case 1:
-		hci_smd_register_dev(&hs);
+		hci_smd_register_smd(&hs);
 	break;
 	case 0:
 		hci_smd_deregister_dev(&hs);
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index c044060..75ec72d 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -42,3 +42,4 @@
 
 # ARM SoC drivers
 obj-$(CONFIG_UX500_SOC_DB8500)		+= db8500-cpufreq.o
+obj-$(CONFIG_MSM_DCVS)			+= cpufreq_gov_msm.o
diff --git a/drivers/cpufreq/cpufreq_gov_msm.c b/drivers/cpufreq/cpufreq_gov_msm.c
new file mode 100644
index 0000000..9c49f80
--- /dev/null
+++ b/drivers/cpufreq/cpufreq_gov_msm.c
@@ -0,0 +1,176 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/kobject.h>
+#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
+#include <mach/msm_dcvs.h>
+
+struct msm_gov {
+	int cpu;
+	unsigned int cur_freq;
+	unsigned int min_freq;
+	unsigned int max_freq;
+	struct msm_dcvs_freq gov_notifier;
+	struct cpufreq_policy *policy;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct mutex, gov_mutex);
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct msm_gov, msm_gov_info);
+static char core_name[NR_CPUS][10];
+
+static void msm_gov_check_limits(struct cpufreq_policy *policy)
+{
+	struct msm_gov *gov = &per_cpu(msm_gov_info, policy->cpu);
+
+	if (policy->max < gov->cur_freq)
+		__cpufreq_driver_target(policy, policy->max,
+				CPUFREQ_RELATION_H);
+	else if (policy->min > gov->min_freq)
+		__cpufreq_driver_target(policy, policy->min,
+				CPUFREQ_RELATION_L);
+	else
+		__cpufreq_driver_target(policy, gov->cur_freq,
+				CPUFREQ_RELATION_L);
+
+	gov->cur_freq = policy->cur;
+	gov->min_freq = policy->min;
+	gov->max_freq = policy->max;
+}
+
+static int msm_dcvs_freq_set(struct msm_dcvs_freq *self,
+		unsigned int freq)
+{
+	int ret = -EINVAL;
+	struct msm_gov *gov =
+		container_of(self, struct msm_gov, gov_notifier);
+
+	mutex_lock(&per_cpu(gov_mutex, gov->cpu));
+
+	if (freq < gov->min_freq)
+		freq = gov->min_freq;
+	if (freq > gov->max_freq)
+		freq = gov->max_freq;
+
+	ret = __cpufreq_driver_target(gov->policy, freq, CPUFREQ_RELATION_L);
+	gov->cur_freq = gov->policy->cur;
+
+	mutex_unlock(&per_cpu(gov_mutex, gov->cpu));
+
+	if (!ret)
+		return gov->cur_freq;
+
+	return ret;
+}
+
+static unsigned int msm_dcvs_freq_get(struct msm_dcvs_freq *self)
+{
+	struct msm_gov *gov =
+		container_of(self, struct msm_gov, gov_notifier);
+
+	return gov->cur_freq;
+}
+
+static int cpufreq_governor_msm(struct cpufreq_policy *policy,
+		unsigned int event)
+{
+	unsigned int cpu = policy->cpu;
+	int ret = 0;
+	int handle = 0;
+	struct msm_gov *gov = &per_cpu(msm_gov_info, policy->cpu);
+	struct msm_dcvs_freq *dcvs_notifier =
+			&(per_cpu(msm_gov_info, cpu).gov_notifier);
+
+	switch (event) {
+	case CPUFREQ_GOV_START:
+		if (!cpu_online(cpu))
+			return -EINVAL;
+		BUG_ON(!policy->cur);
+		mutex_lock(&per_cpu(gov_mutex, cpu));
+		per_cpu(msm_gov_info, cpu).cpu = cpu;
+		gov->policy = policy;
+		dcvs_notifier->core_name = core_name[cpu];
+		dcvs_notifier->set_frequency = msm_dcvs_freq_set;
+		dcvs_notifier->get_frequency = msm_dcvs_freq_get;
+		handle = msm_dcvs_freq_sink_register(dcvs_notifier);
+		BUG_ON(handle < 0);
+		msm_gov_check_limits(policy);
+		mutex_unlock(&per_cpu(gov_mutex, cpu));
+		break;
+
+	case CPUFREQ_GOV_STOP:
+		mutex_lock(&per_cpu(gov_mutex, cpu));
+		msm_dcvs_freq_sink_unregister(dcvs_notifier);
+		mutex_unlock(&per_cpu(gov_mutex, cpu));
+		break;
+
+	case CPUFREQ_GOV_LIMITS:
+		mutex_lock(&per_cpu(gov_mutex, cpu));
+		msm_gov_check_limits(policy);
+		mutex_unlock(&per_cpu(gov_mutex, cpu));
+		break;
+	};
+
+	return ret;
+}
+
+struct cpufreq_governor cpufreq_gov_msm = {
+	.name = "msm-dcvs",
+	.governor = cpufreq_governor_msm,
+	.owner = THIS_MODULE,
+};
+
+static int __devinit msm_gov_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	int cpu;
+	uint32_t group_id = 0x43505530; /* CPU0 */
+	struct msm_dcvs_core_info *core = NULL;
+
+	core = pdev->dev.platform_data;
+
+	for_each_possible_cpu(cpu) {
+		mutex_init(&per_cpu(gov_mutex, cpu));
+		snprintf(core_name[cpu], 10, "cpu%d", cpu);
+		ret = msm_dcvs_register_core(core_name[cpu], group_id, core);
+		if (ret)
+			pr_err("Unable to register core for %d\n", cpu);
+	}
+
+	return cpufreq_register_governor(&cpufreq_gov_msm);
+}
+
+static int __devexit msm_gov_remove(struct platform_device *pdev)
+{
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static struct platform_driver msm_gov_driver = {
+	.probe = msm_gov_probe,
+	.remove = __devexit_p(msm_gov_remove),
+	.driver = {
+		.name = "msm_dcvs_gov",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init cpufreq_gov_msm_init(void)
+{
+	return platform_driver_register(&msm_gov_driver);
+}
+late_initcall(cpufreq_gov_msm_init);
diff --git a/drivers/gpio/pm8xxx-gpio.c b/drivers/gpio/pm8xxx-gpio.c
index 53305e3..f317c37 100644
--- a/drivers/gpio/pm8xxx-gpio.c
+++ b/drivers/gpio/pm8xxx-gpio.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm PMIC8XXX GPIO driver
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -302,7 +302,7 @@
 	pm_gpio_chip->gpio_chip.set = pm_gpio_write;
 	pm_gpio_chip->gpio_chip.dbg_show = pm_gpio_dbg_show;
 	pm_gpio_chip->gpio_chip.ngpio = pdata->gpio_cdata.ngpios;
-	pm_gpio_chip->gpio_chip.can_sleep = 1;
+	pm_gpio_chip->gpio_chip.can_sleep = 0;
 	pm_gpio_chip->gpio_chip.dev = &pdev->dev;
 	pm_gpio_chip->gpio_chip.base = pdata->gpio_base;
 	pm_gpio_chip->irq_base = platform_get_irq(pdev, 0);
diff --git a/drivers/gpio/pm8xxx-mpp.c b/drivers/gpio/pm8xxx-mpp.c
index 82a11a2..9afd5d1 100644
--- a/drivers/gpio/pm8xxx-mpp.c
+++ b/drivers/gpio/pm8xxx-mpp.c
@@ -1,7 +1,7 @@
 /*
  * Qualcomm PM8XXX Multi-Purpose Pin (MPP) driver
  *
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -250,7 +250,7 @@
 	mpp_chip->gpio_chip.set = pm8xxx_mpp_set;
 	mpp_chip->gpio_chip.dbg_show = pm8xxx_mpp_dbg_show;
 	mpp_chip->gpio_chip.ngpio = pdata->core_data.nmpps;
-	mpp_chip->gpio_chip.can_sleep = 1;
+	mpp_chip->gpio_chip.can_sleep = 0;
 	mpp_chip->gpio_chip.dev = &pdev->dev;
 	mpp_chip->gpio_chip.base = pdata->mpp_base;
 	mpp_chip->irq_base = platform_get_irq(pdev, 0);
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 347ab88..7a08e50 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -110,17 +110,15 @@
 					      struct ion_buffer *buffer)
 {
 	struct scatterlist *sglist;
-	struct page *page = phys_to_page(buffer->priv_phys);
-
-	if (page == NULL)
-		return NULL;
 
 	sglist = vmalloc(sizeof(struct scatterlist));
 	if (!sglist)
 		return ERR_PTR(-ENOMEM);
 
 	sg_init_table(sglist, 1);
-	sg_set_page(sglist, page, buffer->size, 0);
+	sglist->length = buffer->size;
+	sglist->offset = 0;
+	sglist->dma_address = buffer->priv_phys;
 
 	return sglist;
 }
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index ff561dc..85c0534 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -299,17 +299,15 @@
 					      struct ion_buffer *buffer)
 {
 	struct scatterlist *sglist;
-	struct page *page = phys_to_page(buffer->priv_phys);
-
-	if (page == NULL)
-		return NULL;
 
 	sglist = vmalloc(sizeof(*sglist));
 	if (!sglist)
 		return ERR_PTR(-ENOMEM);
 
 	sg_init_table(sglist, 1);
-	sg_set_page(sglist, page, buffer->size, 0);
+	sglist->length = buffer->size;
+	sglist->offset = 0;
+	sglist->dma_address = buffer->priv_phys;
 
 	return sglist;
 }
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 8963fc8..c01e676 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/delay.h>
+#include <mach/socinfo.h>
 
 #include "kgsl.h"
 #include "adreno.h"
@@ -2567,10 +2568,11 @@
 	adreno_regwrite(device, A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003C);
 	adreno_regwrite(device, A3XX_VBIF_OUT_AXI_AOOO, 0x003C003C);
 
-	/* Enable 1K sort */
-	adreno_regwrite(device, A3XX_VBIF_ABIT_SORT, 0x000000FF);
-	adreno_regwrite(device, A3XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
-
+	if (cpu_is_apq8064()) {
+		/* Enable 1K sort */
+		adreno_regwrite(device, A3XX_VBIF_ABIT_SORT, 0x000000FF);
+		adreno_regwrite(device, A3XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
+	}
 	/* Make all blocks contribute to the GPU BUSY perf counter */
 	adreno_regwrite(device, A3XX_RBBM_GPU_BUSY_MASKED, 0xFFFFFFFF);
 
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index e4bc470..5b197b4 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -665,7 +665,8 @@
 		"        MPU_END    = %08X | VA_RANGE = %08X | PT_BASE  ="
 		" %08X\n", r1, r2, r3);
 
-	KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ", KGSL_PAGETABLE_SIZE);
+	KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ",
+		kgsl_mmu_get_ptsize());
 
 	kgsl_regread(device, MH_MMU_TRAN_ERROR, &r1);
 	KGSL_LOG_DUMP(device, "        TRAN_ERROR = %08X\n", r1);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 5464bbb..cde568c 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2416,8 +2416,8 @@
 static int __devinit
 kgsl_ptdata_init(void)
 {
-	kgsl_driver.ptpool = kgsl_mmu_ptpool_init(KGSL_PAGETABLE_SIZE,
-						kgsl_pagetable_count);
+	kgsl_driver.ptpool = kgsl_mmu_ptpool_init(kgsl_pagetable_count);
+
 	if (!kgsl_driver.ptpool)
 		return -ENOMEM;
 	return 0;
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 06f78fc..20ed808 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -40,10 +40,6 @@
 #define KGSL_PAGETABLE_ENTRIES(_sz) (((_sz) >> PAGE_SHIFT) + \
 				     KGSL_PT_EXTRA_ENTRIES)
 
-#define KGSL_PAGETABLE_SIZE \
-ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
-KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
-
 #ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
 #define KGSL_PAGETABLE_COUNT (CONFIG_MSM_KGSL_PAGE_TABLE_COUNT)
 #else
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index e9455cb..a972f69 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -359,7 +359,7 @@
 void kgsl_cffdump_open(enum kgsl_deviceid device_id)
 {
 	kgsl_cffdump_memory_base(device_id, KGSL_PAGETABLE_BASE,
-			CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, SZ_256K);
+			kgsl_mmu_get_ptsize(), SZ_256K);
 }
 
 void kgsl_cffdump_memory_base(enum kgsl_deviceid device_id, unsigned int base,
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 97b5ef1..942aa12 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -22,6 +22,10 @@
 #include "kgsl_device.h"
 #include "kgsl_sharedmem.h"
 
+#define KGSL_PAGETABLE_SIZE \
+	ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
+	KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
+
 static ssize_t
 sysfs_show_ptpool_entries(struct kobject *kobj,
 			  struct kobj_attribute *attr,
@@ -310,16 +314,15 @@
 /**
  * kgsl_ptpool_init
  * @pool:  A pointer to a ptpool structure to initialize
- * @ptsize: The size of each pagetable entry
  * @entries:  The number of inital entries to add to the pool
  *
  * Initalize a pool and allocate an initial chunk of entries.
  */
-void *kgsl_gpummu_ptpool_init(int ptsize, int entries)
+void *kgsl_gpummu_ptpool_init(int entries)
 {
+	int ptsize = KGSL_PAGETABLE_SIZE;
 	struct kgsl_ptpool *pool;
 	int ret = 0;
-	BUG_ON(ptsize == 0);
 
 	pool = kzalloc(sizeof(struct kgsl_ptpool), GFP_KERNEL);
 	if (!pool) {
@@ -682,7 +685,7 @@
 		flushtlb = 1;
 
 	for_each_sg(memdesc->sg, s, memdesc->sglen, i) {
-		unsigned int paddr = sg_phys(s);
+		unsigned int paddr = kgsl_get_sg_pa(s);
 		unsigned int j;
 
 		/* Each sg entry might be multiple pages long */
diff --git a/drivers/gpu/msm/kgsl_gpummu.h b/drivers/gpu/msm/kgsl_gpummu.h
index 46466a8..cac6930 100644
--- a/drivers/gpu/msm/kgsl_gpummu.h
+++ b/drivers/gpu/msm/kgsl_gpummu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -73,8 +73,7 @@
 	int chunks;
 };
 
-void *kgsl_gpummu_ptpool_init(int ptsize,
-			int entries);
+void *kgsl_gpummu_ptpool_init(int entries);
 void kgsl_gpummu_ptpool_destroy(void *ptpool);
 
 static inline unsigned int kgsl_pt_get_base_addr(struct kgsl_pagetable *pt)
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 0ea52c4..ceb3212 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -148,9 +148,10 @@
 
 	pt = _get_pt_from_kobj(kobj);
 
-	if (pt)
+	if (pt) {
 		ret += snprintf(buf, PAGE_SIZE, "0x%x\n",
-			CONFIG_MSM_KGSL_PAGE_TABLE_SIZE);
+			kgsl_mmu_get_ptsize());
+	}
 
 	kgsl_put_pagetable(pt);
 	return ret;
@@ -268,6 +269,22 @@
 	return ret;
 }
 
+unsigned int kgsl_mmu_get_ptsize(void)
+{
+	/*
+	 * For IOMMU, we could do up to 4G virtual range if we wanted to, but
+	 * it makes more sense to return a smaller range and leave the rest of
+	 * the virtual range for future improvements
+	 */
+
+	if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type)
+		return CONFIG_MSM_KGSL_PAGE_TABLE_SIZE;
+	else if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_type)
+		return SZ_2G;
+	else
+		return 0;
+}
+
 unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_device *device)
 {
 	struct kgsl_mmu *mmu = &device->mmu;
@@ -392,6 +409,7 @@
 	int status = 0;
 	struct kgsl_pagetable *pagetable = NULL;
 	unsigned long flags;
+	unsigned int ptsize;
 
 	pagetable = kzalloc(sizeof(struct kgsl_pagetable), GFP_KERNEL);
 	if (pagetable == NULL) {
@@ -403,9 +421,11 @@
 	kref_init(&pagetable->refcount);
 
 	spin_lock_init(&pagetable->lock);
+
+	ptsize = kgsl_mmu_get_ptsize();
+
 	pagetable->name = name;
-	pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(
-					CONFIG_MSM_KGSL_PAGE_TABLE_SIZE);
+	pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(ptsize);
 
 	pagetable->pool = gen_pool_create(PAGE_SHIFT, -1);
 	if (pagetable->pool == NULL) {
@@ -414,7 +434,7 @@
 	}
 
 	if (gen_pool_add(pagetable->pool, KGSL_PAGETABLE_BASE,
-				CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, -1)) {
+				ptsize, -1)) {
 		KGSL_CORE_ERR("gen_pool_add failed\n");
 		goto err_pool;
 	}
@@ -556,8 +576,11 @@
 		return -ENOMEM;
 	}
 
-	spin_lock(&pagetable->lock);
+	if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
+		spin_lock(&pagetable->lock);
 	ret = pagetable->pt_ops->mmu_map(pagetable->priv, memdesc, protflags);
+	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
+		spin_lock(&pagetable->lock);
 
 	if (ret)
 		goto err_free_gpuaddr;
@@ -593,8 +616,11 @@
 		memdesc->gpuaddr = 0;
 		return 0;
 	}
-	spin_lock(&pagetable->lock);
+	if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
+		spin_lock(&pagetable->lock);
 	pagetable->pt_ops->mmu_unmap(pagetable->priv, memdesc);
+	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
+		spin_lock(&pagetable->lock);
 	/* Remove the statistics */
 	pagetable->stats.entries--;
 	pagetable->stats.mapped -= memdesc->size;
@@ -691,10 +717,10 @@
 }
 EXPORT_SYMBOL(kgsl_mmu_ptpool_destroy);
 
-void *kgsl_mmu_ptpool_init(int ptsize, int entries)
+void *kgsl_mmu_ptpool_init(int entries)
 {
 	if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type)
-		return kgsl_gpummu_ptpool_init(ptsize, entries);
+		return kgsl_gpummu_ptpool_init(entries);
 	else
 		return (void *)(-1);
 }
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 1338d0d..0ff5881 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -175,13 +175,13 @@
 int kgsl_mmu_get_ptname_from_ptbase(unsigned int pt_base);
 int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
 			enum kgsl_deviceid id);
-
 void kgsl_mmu_ptpool_destroy(void *ptpool);
-void *kgsl_mmu_ptpool_init(int ptsize, int entries);
+void *kgsl_mmu_ptpool_init(int entries);
 int kgsl_mmu_enabled(void);
 int kgsl_mmu_pt_equal(struct kgsl_pagetable *pt,
 			unsigned int pt_base);
 void kgsl_mmu_set_mmutype(char *mmutype);
 unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_device *device);
 enum kgsl_mmutype kgsl_mmu_get_mmutype(void);
+unsigned int kgsl_mmu_get_ptsize(void);
 #endif /* __KGSL_MMU_H */
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index f61a196..d083702 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -284,7 +284,7 @@
 	int i;
 
 	for_each_sg(sg, s, sglen, i) {
-		unsigned int paddr = sg_phys(s);
+		unsigned int paddr = kgsl_get_sg_pa(s);
 		_outer_cache_range_op(op, paddr, s->length);
 	}
 }
diff --git a/drivers/gpu/msm/kgsl_sharedmem.h b/drivers/gpu/msm/kgsl_sharedmem.h
index af0d74d..a1e4c91 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.h
+++ b/drivers/gpu/msm/kgsl_sharedmem.h
@@ -80,12 +80,22 @@
 int kgsl_sharedmem_init_sysfs(void);
 void kgsl_sharedmem_uninit_sysfs(void);
 
+static inline unsigned int kgsl_get_sg_pa(struct scatterlist *sg)
+{
+	/*
+	 * Try sg_dma_address first to support ion carveout
+	 * regions which do not work with sg_phys().
+	 */
+	unsigned int pa = sg_dma_address(sg);
+	if (pa == 0)
+		pa = sg_phys(sg);
+	return pa;
+}
+
 static inline int
 memdesc_sg_phys(struct kgsl_memdesc *memdesc,
 		unsigned int physaddr, unsigned int size)
 {
-	struct page *page = phys_to_page(physaddr);
-
 	memdesc->sg = vmalloc(sizeof(struct scatterlist) * 1);
 	if (memdesc->sg == NULL)
 		return -ENOMEM;
@@ -94,7 +104,9 @@
 
 	memdesc->sglen = 1;
 	sg_init_table(memdesc->sg, 1);
-	sg_set_page(&memdesc->sg[0], page, size, 0);
+	memdesc->sg[0].length = size;
+	memdesc->sg[0].offset = 0;
+	memdesc->sg[0].dma_address = physaddr;
 	return 0;
 }
 
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 0902c61..2f59235 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.c
@@ -131,7 +131,6 @@
 	struct mutex				adc_lock;
 	struct mutex				mpp_adc_lock;
 	spinlock_t				btm_lock;
-	uint32_t				adc_num_channel;
 	uint32_t				adc_num_board_channel;
 	struct completion			adc_rslt_completion;
 	struct pm8xxx_adc_amux			*adc_channel;
@@ -201,6 +200,17 @@
 static bool pm8xxx_adc_calib_first_adc;
 static bool pm8xxx_adc_initialized, pm8xxx_adc_calib_device_init;
 
+static int32_t pm8xxx_adc_check_channel_valid(uint32_t channel)
+{
+	if (channel < CHANNEL_VCOIN ||
+	(channel > CHANNEL_MUXOFF && channel < ADC_MPP_1_ATEST_8) ||
+	(channel > ADC_MPP_1_ATEST_7 && channel < ADC_MPP_2_ATEST_8)
+	|| (channel >= ADC_CHANNEL_MAX_NUM))
+		return -EBADF;
+	else
+		return 0;
+}
+
 static int32_t pm8xxx_adc_arb_cntrl(uint32_t arb_cntrl,
 					uint32_t channel)
 {
@@ -675,12 +685,13 @@
 
 	mutex_lock(&adc_pmic->adc_lock);
 
-	for (i = 0; i < adc_pmic->adc_num_channel; i++) {
+	for (i = 0; i < adc_pmic->adc_num_board_channel; i++) {
 		if (channel == adc_pmic->adc_channel[i].channel_name)
 			break;
 	}
 
-	if (i == adc_pmic->adc_num_channel) {
+	if (i == adc_pmic->adc_num_board_channel ||
+		(pm8xxx_adc_check_channel_valid(channel) != 0)) {
 		rc = -EBADF;
 		goto fail_unlock;
 	}
@@ -1001,12 +1012,10 @@
 			struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct pm8xxx_adc *adc_pmic = pmic_adc;
 	struct pm8xxx_adc_chan_result result;
 	int rc = -1;
 
-	if (attr->index < adc_pmic->adc_num_channel)
-		rc = pm8xxx_adc_read(attr->index, &result);
+	rc = pm8xxx_adc_read(attr->index, &result);
 
 	if (rc)
 		return 0;
@@ -1076,9 +1085,14 @@
 static int32_t pm8xxx_adc_init_hwmon(struct platform_device *pdev)
 {
 	struct pm8xxx_adc *adc_pmic = pmic_adc;
-	int rc = 0, i;
+	int rc = 0, i, channel;
 
 	for (i = 0; i < pmic_adc->adc_num_board_channel; i++) {
+		channel = adc_pmic->adc_channel[i].channel_name;
+		if (pm8xxx_adc_check_channel_valid(channel)) {
+			pr_err("Invalid ADC init HWMON channel: %d\n", channel);
+			continue;
+		}
 		pm8xxx_adc_attr.index = adc_pmic->adc_channel[i].channel_name;
 		pm8xxx_adc_attr.dev_attr.attr.name =
 						adc_pmic->adc_channel[i].name;
@@ -1184,7 +1198,6 @@
 	init_completion(&adc_pmic->adc_rslt_completion);
 	adc_pmic->adc_channel = pdata->adc_channel;
 	adc_pmic->adc_num_board_channel = pdata->adc_num_board_channel;
-	adc_pmic->adc_num_channel = ADC_MPP_2_CHANNEL_NONE;
 	adc_pmic->mpp_base = pdata->adc_mpp_base;
 
 	mutex_init(&adc_pmic->adc_lock);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 87cdb02..eef0891 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -817,4 +817,18 @@
 
          To compile this driver as a module, choose M here: the
          module will be called cyttsp-i2c.
+
+config TOUCHSCREEN_FT5X06
+       tristate "FocalTech touchscreens"
+       depends on I2C
+       help
+         Say Y here if you have a ft5X06 touchscreen.
+	 Ft5x06 controllers are multi touch controllers which can
+	 report 5 touches at a time.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ft5x06_ts.
+
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 1d67427..616b3a4 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -26,6 +26,7 @@
 obj-$(CONFIG_TOUCHSCREEN_EETI)		+= eeti_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ELAN_I2C_8232) += elan8232_i2c.o
 obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
+obj-$(CONFIG_TOUCHSCREEN_FT5X06)	+= ft5x06_ts.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
diff --git a/drivers/input/touchscreen/ft5x06_ts.c b/drivers/input/touchscreen/ft5x06_ts.c
new file mode 100644
index 0000000..c9905a4
--- /dev/null
+++ b/drivers/input/touchscreen/ft5x06_ts.c
@@ -0,0 +1,654 @@
+/*
+ *
+ * FocalTech ft5x06 TouchScreen driver.
+ *
+ * Copyright (c) 2010  Focal tech Ltd.
+ * Copyright (c) 2012, Code Aurora Forum. 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.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/input/ft5x06_ts.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+/* Early-suspend level */
+#define FT5X06_SUSPEND_LEVEL 1
+#endif
+
+#define CFG_MAX_TOUCH_POINTS	5
+
+#define FT_STARTUP_DLY		150
+#define FT_RESET_DLY		20
+
+#define FT_PRESS		0x7F
+#define FT_MAX_ID		0x0F
+#define FT_TOUCH_STEP		6
+#define FT_TOUCH_X_H_POS	3
+#define FT_TOUCH_X_L_POS	4
+#define FT_TOUCH_Y_H_POS	5
+#define FT_TOUCH_Y_L_POS	6
+#define FT_TOUCH_EVENT_POS	3
+#define FT_TOUCH_ID_POS		5
+
+#define POINT_READ_BUF	(3 + FT_TOUCH_STEP * CFG_MAX_TOUCH_POINTS)
+
+/*register address*/
+#define FT5X06_REG_PMODE	0xA5
+#define FT5X06_REG_FW_VER	0xA6
+#define FT5X06_REG_POINT_RATE	0x88
+#define FT5X06_REG_THGROUP	0x80
+
+/* power register bits*/
+#define FT5X06_PMODE_ACTIVE		0x00
+#define FT5X06_PMODE_MONITOR		0x01
+#define FT5X06_PMODE_STANDBY		0x02
+#define FT5X06_PMODE_HIBERNATE		0x03
+
+#define FT5X06_VTG_MIN_UV	2600000
+#define FT5X06_VTG_MAX_UV	3300000
+#define FT5X06_I2C_VTG_MIN_UV	1800000
+#define FT5X06_I2C_VTG_MAX_UV	1800000
+
+struct ts_event {
+	u16 x[CFG_MAX_TOUCH_POINTS];	/*x coordinate */
+	u16 y[CFG_MAX_TOUCH_POINTS];	/*y coordinate */
+	/* touch event: 0 -- down; 1-- contact; 2 -- contact */
+	u8 touch_event[CFG_MAX_TOUCH_POINTS];
+	u8 finger_id[CFG_MAX_TOUCH_POINTS];	/*touch ID */
+	u16 pressure;
+	u8 touch_point;
+};
+
+struct ft5x06_ts_data {
+	struct i2c_client *client;
+	struct input_dev *input_dev;
+	struct ts_event event;
+	const struct ft5x06_ts_platform_data *pdata;
+	struct regulator *vdd;
+	struct regulator *vcc_i2c;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct early_suspend early_suspend;
+#endif
+};
+
+static int ft5x06_i2c_read(struct i2c_client *client, char *writebuf,
+			   int writelen, char *readbuf, int readlen)
+{
+	int ret;
+
+	if (writelen > 0) {
+		struct i2c_msg msgs[] = {
+			{
+				 .addr = client->addr,
+				 .flags = 0,
+				 .len = writelen,
+				 .buf = writebuf,
+			 },
+			{
+				 .addr = client->addr,
+				 .flags = I2C_M_RD,
+				 .len = readlen,
+				 .buf = readbuf,
+			 },
+		};
+		ret = i2c_transfer(client->adapter, msgs, 2);
+		if (ret < 0)
+			dev_err(&client->dev, "%s: i2c read error.\n",
+				__func__);
+	} else {
+		struct i2c_msg msgs[] = {
+			{
+				 .addr = client->addr,
+				 .flags = I2C_M_RD,
+				 .len = readlen,
+				 .buf = readbuf,
+			 },
+		};
+		ret = i2c_transfer(client->adapter, msgs, 1);
+		if (ret < 0)
+			dev_err(&client->dev, "%s:i2c read error.\n", __func__);
+	}
+	return ret;
+}
+
+static int ft5x06_i2c_write(struct i2c_client *client, char *writebuf,
+			    int writelen)
+{
+	int ret;
+
+	struct i2c_msg msgs[] = {
+		{
+			 .addr = client->addr,
+			 .flags = 0,
+			 .len = writelen,
+			 .buf = writebuf,
+		 },
+	};
+	ret = i2c_transfer(client->adapter, msgs, 1);
+	if (ret < 0)
+		dev_err(&client->dev, "%s: i2c write error.\n", __func__);
+
+	return ret;
+}
+
+static void ft5x06_report_value(struct ft5x06_ts_data *data)
+{
+	struct ts_event *event = &data->event;
+	int i;
+	int fingerdown = 0;
+
+	for (i = 0; i < event->touch_point; i++) {
+		if (event->touch_event[i] == 0 || event->touch_event[i] == 2) {
+			event->pressure = FT_PRESS;
+			fingerdown++;
+		} else {
+			event->pressure = 0;
+		}
+
+		input_report_abs(data->input_dev, ABS_MT_POSITION_X,
+				 event->x[i]);
+		input_report_abs(data->input_dev, ABS_MT_POSITION_Y,
+				 event->y[i]);
+		input_report_abs(data->input_dev, ABS_MT_PRESSURE,
+				 event->pressure);
+		input_report_abs(data->input_dev, ABS_MT_TRACKING_ID,
+				 event->finger_id[i]);
+		input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR,
+				 event->pressure);
+		input_mt_sync(data->input_dev);
+	}
+
+	input_report_key(data->input_dev, BTN_TOUCH, !!fingerdown);
+	input_sync(data->input_dev);
+}
+
+static int ft5x06_handle_touchdata(struct ft5x06_ts_data *data)
+{
+	struct ts_event *event = &data->event;
+	int ret, i;
+	u8 buf[POINT_READ_BUF] = { 0 };
+	u8 pointid = FT_MAX_ID;
+
+	ret = ft5x06_i2c_read(data->client, buf, 1, buf, POINT_READ_BUF);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "%s read touchdata failed.\n",
+			__func__);
+		return ret;
+	}
+	memset(event, 0, sizeof(struct ts_event));
+
+	event->touch_point = 0;
+	for (i = 0; i < CFG_MAX_TOUCH_POINTS; i++) {
+		pointid = (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
+		if (pointid >= FT_MAX_ID)
+			break;
+		else
+			event->touch_point++;
+		event->x[i] =
+		    (s16) (buf[FT_TOUCH_X_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
+		    8 | (s16) buf[FT_TOUCH_X_L_POS + FT_TOUCH_STEP * i];
+		event->y[i] =
+		    (s16) (buf[FT_TOUCH_Y_H_POS + FT_TOUCH_STEP * i] & 0x0F) <<
+		    8 | (s16) buf[FT_TOUCH_Y_L_POS + FT_TOUCH_STEP * i];
+		event->touch_event[i] =
+		    buf[FT_TOUCH_EVENT_POS + FT_TOUCH_STEP * i] >> 6;
+		event->finger_id[i] =
+		    (buf[FT_TOUCH_ID_POS + FT_TOUCH_STEP * i]) >> 4;
+	}
+
+	ft5x06_report_value(data);
+
+	return 0;
+}
+
+static irqreturn_t ft5x06_ts_interrupt(int irq, void *dev_id)
+{
+	struct ft5x06_ts_data *data = dev_id;
+	int rc;
+
+	rc = ft5x06_handle_touchdata(data);
+	if (rc)
+		pr_err("%s: handling touchdata failed\n", __func__);
+
+	return IRQ_HANDLED;
+}
+
+static int ft5x06_power_on(struct ft5x06_ts_data *data, bool on)
+{
+	int rc;
+
+	if (!on)
+		goto power_off;
+
+	rc = regulator_enable(data->vdd);
+	if (rc) {
+		dev_err(&data->client->dev,
+			"Regulator vdd enable failed rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = regulator_enable(data->vcc_i2c);
+	if (rc) {
+		dev_err(&data->client->dev,
+			"Regulator vcc_i2c enable failed rc=%d\n", rc);
+		regulator_disable(data->vdd);
+	}
+
+	return rc;
+
+power_off:
+	rc = regulator_disable(data->vdd);
+	if (rc) {
+		dev_err(&data->client->dev,
+			"Regulator vdd disable failed rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = regulator_disable(data->vcc_i2c);
+	if (rc) {
+		dev_err(&data->client->dev,
+			"Regulator vcc_i2c disable failed rc=%d\n", rc);
+		regulator_enable(data->vdd);
+	}
+
+	return rc;
+}
+
+static int ft5x06_power_init(struct ft5x06_ts_data *data, bool on)
+{
+	int rc;
+
+	if (!on)
+		goto pwr_deinit;
+
+	data->vdd = regulator_get(&data->client->dev, "vdd");
+	if (IS_ERR(data->vdd)) {
+		rc = PTR_ERR(data->vdd);
+		dev_err(&data->client->dev,
+			"Regulator get failed vdd rc=%d\n", rc);
+		return rc;
+	}
+
+	if (regulator_count_voltages(data->vdd) > 0) {
+		rc = regulator_set_voltage(data->vdd, FT5X06_VTG_MIN_UV,
+					   FT5X06_VTG_MAX_UV);
+		if (rc) {
+			dev_err(&data->client->dev,
+				"Regulator set_vtg failed vdd rc=%d\n", rc);
+			goto reg_vdd_put;
+		}
+	}
+
+	data->vcc_i2c = regulator_get(&data->client->dev, "vcc_i2c");
+	if (IS_ERR(data->vcc_i2c)) {
+		rc = PTR_ERR(data->vcc_i2c);
+		dev_err(&data->client->dev,
+			"Regulator get failed vcc_i2c rc=%d\n", rc);
+		goto reg_vdd_set_vtg;
+	}
+
+	if (regulator_count_voltages(data->vcc_i2c) > 0) {
+		rc = regulator_set_voltage(data->vcc_i2c, FT5X06_I2C_VTG_MIN_UV,
+					   FT5X06_I2C_VTG_MAX_UV);
+		if (rc) {
+			dev_err(&data->client->dev,
+			"Regulator set_vtg failed vcc_i2c rc=%d\n", rc);
+			goto reg_vcc_i2c_put;
+		}
+	}
+
+	return 0;
+
+reg_vcc_i2c_put:
+	regulator_put(data->vcc_i2c);
+reg_vdd_set_vtg:
+	if (regulator_count_voltages(data->vdd) > 0)
+		regulator_set_voltage(data->vdd, 0, FT5X06_VTG_MAX_UV);
+reg_vdd_put:
+	regulator_put(data->vdd);
+	return rc;
+
+pwr_deinit:
+	if (regulator_count_voltages(data->vdd) > 0)
+		regulator_set_voltage(data->vdd, 0, FT5X06_VTG_MAX_UV);
+
+	regulator_put(data->vdd);
+
+	if (regulator_count_voltages(data->vcc_i2c) > 0)
+		regulator_set_voltage(data->vcc_i2c, 0, FT5X06_I2C_VTG_MAX_UV);
+
+	regulator_put(data->vcc_i2c);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ft5x06_ts_suspend(struct device *dev)
+{
+	struct ft5x06_ts_data *data = dev_get_drvdata(dev);
+	char txbuf[2];
+
+	disable_irq(data->client->irq);
+
+	if (gpio_is_valid(data->pdata->reset_gpio)) {
+		txbuf[0] = FT5X06_REG_PMODE;
+		txbuf[1] = FT5X06_PMODE_HIBERNATE;
+		ft5x06_i2c_write(data->client, txbuf, sizeof(txbuf));
+	}
+
+	return 0;
+}
+
+static int ft5x06_ts_resume(struct device *dev)
+{
+	struct ft5x06_ts_data *data = dev_get_drvdata(dev);
+
+	if (gpio_is_valid(data->pdata->reset_gpio)) {
+		gpio_set_value_cansleep(data->pdata->reset_gpio, 0);
+		msleep(FT_RESET_DLY);
+		gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
+	}
+	enable_irq(data->client->irq);
+
+	return 0;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void ft5x06_ts_early_suspend(struct early_suspend *handler)
+{
+	struct ft5x06_ts_data *data = container_of(handler,
+						   struct ft5x06_ts_data,
+						   early_suspend);
+
+	ft5x06_ts_suspend(&data->client->dev);
+}
+
+static void ft5x06_ts_late_resume(struct early_suspend *handler)
+{
+	struct ft5x06_ts_data *data = container_of(handler,
+						   struct ft5x06_ts_data,
+						   early_suspend);
+
+	ft5x06_ts_resume(&data->client->dev);
+}
+#endif
+
+static const struct dev_pm_ops ft5x06_ts_pm_ops = {
+#ifndef CONFIG_HAS_EARLYSUSPEND
+	.suspend = ft5x06_ts_suspend,
+	.resume = ft5x06_ts_resume,
+#endif
+};
+#endif
+
+static int ft5x06_ts_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
+{
+	const struct ft5x06_ts_platform_data *pdata = client->dev.platform_data;
+	struct ft5x06_ts_data *data;
+	struct input_dev *input_dev;
+	u8 reg_value;
+	u8 reg_addr;
+	int err;
+
+	if (!pdata) {
+		dev_err(&client->dev, "Invalid pdata\n");
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "I2C not supported\n");
+		return -ENODEV;
+	}
+
+	data = kzalloc(sizeof(struct ft5x06_ts_data), GFP_KERNEL);
+	if (!data) {
+		dev_err(&client->dev, "Not enough memory\n");
+		return -ENOMEM;
+	}
+
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		err = -ENOMEM;
+		dev_err(&client->dev, "failed to allocate input device\n");
+		goto free_mem;
+	}
+
+	data->input_dev = input_dev;
+	data->client = client;
+	data->pdata = pdata;
+
+	input_dev->name = "ft5x06_ts";
+	input_dev->id.bustype = BUS_I2C;
+	input_dev->dev.parent = &client->dev;
+
+	input_set_drvdata(input_dev, data);
+	i2c_set_clientdata(client, data);
+
+	__set_bit(EV_KEY, input_dev->evbit);
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(BTN_TOUCH, input_dev->keybit);
+
+	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
+			     pdata->x_max, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
+			     pdata->y_max, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
+			     CFG_MAX_TOUCH_POINTS, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, FT_PRESS, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, FT_PRESS, 0, 0);
+
+	err = input_register_device(input_dev);
+	if (err) {
+		dev_err(&client->dev, "Input device registration failed\n");
+		goto free_inputdev;
+	}
+
+	if (pdata->power_init) {
+		err = pdata->power_init(true);
+		if (err) {
+			dev_err(&client->dev, "power init failed");
+			goto unreg_inputdev;
+		}
+	} else {
+		err = ft5x06_power_init(data, true);
+		if (err) {
+			dev_err(&client->dev, "power init failed");
+			goto unreg_inputdev;
+		}
+	}
+
+	if (pdata->power_on) {
+		err = pdata->power_on(true);
+		if (err) {
+			dev_err(&client->dev, "power on failed");
+			goto pwr_deinit;
+		}
+	} else {
+		err = ft5x06_power_on(data, true);
+		if (err) {
+			dev_err(&client->dev, "power on failed");
+			goto pwr_deinit;
+		}
+	}
+
+	if (gpio_is_valid(pdata->irq_gpio)) {
+		err = gpio_request(pdata->irq_gpio, "ft5x06_irq_gpio");
+		if (err) {
+			dev_err(&client->dev, "irq gpio request failed");
+			goto pwr_off;
+		}
+		err = gpio_direction_input(pdata->irq_gpio);
+		if (err) {
+			dev_err(&client->dev,
+				"set_direction for irq gpio failed\n");
+			goto free_irq_gpio;
+		}
+	}
+
+	if (gpio_is_valid(pdata->reset_gpio)) {
+		err = gpio_request(pdata->reset_gpio, "ft5x06_reset_gpio");
+		if (err) {
+			dev_err(&client->dev, "reset gpio request failed");
+			goto free_irq_gpio;
+		}
+
+		err = gpio_direction_output(pdata->reset_gpio, 0);
+		if (err) {
+			dev_err(&client->dev,
+				"set_direction for reset gpio failed\n");
+			goto free_reset_gpio;
+		}
+		msleep(FT_RESET_DLY);
+		gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
+	}
+
+	/* make sure CTP already finish startup process */
+	msleep(FT_STARTUP_DLY);
+
+	/*get some register information */
+	reg_addr = FT5X06_REG_FW_VER;
+	err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
+	if (err)
+		dev_err(&client->dev, "version read failed");
+
+	dev_info(&client->dev, "[FTS] Firmware version = 0x%x\n", reg_value);
+
+	reg_addr = FT5X06_REG_POINT_RATE;
+	ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
+	if (err)
+		dev_err(&client->dev, "report rate read failed");
+	dev_info(&client->dev, "[FTS] report rate is %dHz.\n", reg_value * 10);
+
+	reg_addr = FT5X06_REG_THGROUP;
+	err = ft5x06_i2c_read(client, &reg_addr, 1, &reg_value, 1);
+	if (err)
+		dev_err(&client->dev, "threshold read failed");
+	dev_dbg(&client->dev, "[FTS] touch threshold is %d.\n", reg_value * 4);
+
+	err = request_threaded_irq(client->irq, NULL,
+				   ft5x06_ts_interrupt, pdata->irqflags,
+				   client->dev.driver->name, data);
+	if (err) {
+		dev_err(&client->dev, "request irq failed\n");
+		goto free_reset_gpio;
+	}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
+	    FT5X06_SUSPEND_LEVEL;
+	data->early_suspend.suspend = ft5x06_ts_early_suspend;
+	data->early_suspend.resume = ft5x06_ts_late_resume;
+	register_early_suspend(&data->early_suspend);
+#endif
+
+	return 0;
+
+free_reset_gpio:
+	if (gpio_is_valid(pdata->reset_gpio))
+		gpio_free(pdata->reset_gpio);
+free_irq_gpio:
+	if (gpio_is_valid(pdata->irq_gpio))
+		gpio_free(pdata->reset_gpio);
+pwr_off:
+	if (pdata->power_on)
+		pdata->power_on(false);
+	else
+		ft5x06_power_on(data, false);
+pwr_deinit:
+	if (pdata->power_init)
+		pdata->power_init(false);
+	else
+		ft5x06_power_init(data, false);
+unreg_inputdev:
+	input_unregister_device(input_dev);
+	input_dev = NULL;
+free_inputdev:
+	input_free_device(input_dev);
+free_mem:
+	kfree(data);
+	return err;
+}
+
+static int __devexit ft5x06_ts_remove(struct i2c_client *client)
+{
+	struct ft5x06_ts_data *data = i2c_get_clientdata(client);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	unregister_early_suspend(&data->early_suspend);
+#endif
+	free_irq(client->irq, data);
+
+	if (gpio_is_valid(data->pdata->reset_gpio))
+		gpio_free(data->pdata->reset_gpio);
+
+	if (gpio_is_valid(data->pdata->irq_gpio))
+		gpio_free(data->pdata->reset_gpio);
+
+	if (data->pdata->power_on)
+		data->pdata->power_on(false);
+	else
+		ft5x06_power_on(data, false);
+
+	if (data->pdata->power_init)
+		data->pdata->power_init(false);
+	else
+		ft5x06_power_init(data, false);
+
+	input_unregister_device(data->input_dev);
+	kfree(data);
+
+	return 0;
+}
+
+static const struct i2c_device_id ft5x06_ts_id[] = {
+	{"ft5x06_ts", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, ft5x06_ts_id);
+
+static struct i2c_driver ft5x06_ts_driver = {
+	.probe = ft5x06_ts_probe,
+	.remove = __devexit_p(ft5x06_ts_remove),
+	.driver = {
+		   .name = "ft5x06_ts",
+		   .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+		   .pm = &ft5x06_ts_pm_ops,
+#endif
+		   },
+	.id_table = ft5x06_ts_id,
+};
+
+static int __init ft5x06_ts_init(void)
+{
+	return i2c_add_driver(&ft5x06_ts_driver);
+}
+module_init(ft5x06_ts_init);
+
+static void __exit ft5x06_ts_exit(void)
+{
+	i2c_del_driver(&ft5x06_ts_driver);
+}
+module_exit(ft5x06_ts_exit);
+
+MODULE_DESCRIPTION("FocalTech ft5x06 TouchScreen driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index c3331f8..ab732b2 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -3356,12 +3356,7 @@
 					struct v4l2_hw_freq_seek *seek)
 {
 	struct iris_device *radio = video_get_drvdata(video_devdata(file));
-	int dir;
-	if (seek->seek_upward)
-		dir = SRCH_DIR_UP;
-	else
-		dir = SRCH_DIR_DOWN;
-	return iris_search(radio, CTRL_ON, dir);
+	return iris_search(radio, CTRL_ON, seek->seek_upward);
 }
 
 static int iris_vidioc_querycap(struct file *file, void *priv,
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 288ec6d..fb73321 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -3001,7 +3001,7 @@
 			 * queue the READY event from the host side
 			 * in case of FM off
 			 */
-			tavarua_q_event(radio, TAVARUA_EVT_RADIO_READY);
+			tavarua_q_event(radio, TAVARUA_EVT_RADIO_DISABLED);
 
 			FMDBG("%s, Disable All Interrupts\n", __func__);
 			/* disable irq */
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index 476615d..3a642c7 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -142,6 +142,7 @@
 	struct csic_device *csic_dev;
 	struct msm_camera_csi_params *csic_params;
 	void __iomem *csicbase;
+	int i;
 
 	csic_dev = v4l2_get_subdevdata(cfg_params->subdev);
 	csicbase = csic_dev->base;
@@ -163,24 +164,14 @@
 	CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val);
 	msm_io_w(val, csicbase + MIPI_PROTOCOL_CONTROL);
 
-	val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) |
-		(0x1 <<
-		MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) |
-		(0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) |
-		(0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT);
-	CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val);
-	msm_io_w(val, csicbase + MIPI_CALIBRATION_CONTROL);
-
 	val = (csic_params->settle_cnt <<
 		MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) |
 		(0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) |
 		(0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) |
 		(0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT);
 	CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val);
-	msm_io_w(val, csicbase + MIPI_PHY_D0_CONTROL2);
-	msm_io_w(val, csicbase + MIPI_PHY_D1_CONTROL2);
-	msm_io_w(val, csicbase + MIPI_PHY_D2_CONTROL2);
-	msm_io_w(val, csicbase + MIPI_PHY_D3_CONTROL2);
+	for (i = 0; i < csic_params->lane_cnt; i++)
+		msm_io_w(val, csicbase + MIPI_PHY_D0_CONTROL2 + i * 4);
 
 
 	val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) |
@@ -233,7 +224,9 @@
 
 	pr_info("msm_csic_irq: %x\n", (unsigned int)csic_dev->base);
 	irq = msm_io_r(csic_dev->base + MIPI_INTERRUPT_STATUS);
-	pr_info("%s MIPI_INTERRUPT_STATUS = 0x%x\n", __func__, irq);
+	pr_info("%s MIPI_INTERRUPT_STATUS = 0x%x 0x%x\n",
+			__func__, irq,
+			msm_io_r(csic_dev->base + MIPI_PROTOCOL_CONTROL));
 	msm_io_w(irq, csic_dev->base + MIPI_INTERRUPT_STATUS);
 
 	/* TODO: Needs to send this info to upper layers */
@@ -372,7 +365,7 @@
 	}
 
 	rc = request_irq(new_csic_dev->irq->start, msm_csic_irq,
-		IRQF_TRIGGER_RISING, "csic", new_csic_dev);
+			IRQF_TRIGGER_HIGH, "csic", new_csic_dev);
 	if (rc < 0) {
 		release_mem_region(new_csic_dev->mem->start,
 			resource_size(new_csic_dev->mem));
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index e1f4532..a332fba 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -614,6 +614,24 @@
 				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
 						cmd_data, len);
 				vfe2x_ctrl->start_pending = 0;
+			} else if (vfe2x_ctrl->stop_pending) {
+				CDBG("Send STOP\n");
+				cmd_data = buf;
+				*(uint32_t *)cmd_data = VFE_STOP;
+				/* Send Stop cmd here */
+				len  = 4;
+				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+						cmd_data, len);
+				vfe2x_ctrl->stop_pending = 0;
+			} else if (vfe2x_ctrl->update_pending) {
+				CDBG("Send Update\n");
+				cmd_data = buf;
+				*(uint32_t *)cmd_data = VFE_UPDATE;
+				/* Send Update cmd here */
+				len  = 4;
+				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+						cmd_data, len);
+				vfe2x_ctrl->update_pending = 0;
 			}
 			vfe2x_ctrl->tableack_pending = 0;
 			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
@@ -1105,7 +1123,9 @@
 			case VFE_CMD_CAPTURE_RAW:
 				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
 									flags);
-				if (!list_empty(&vfe2x_ctrl->table_q)) {
+				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+						vfe2x_ctrl->tableack_pending) {
+					CDBG("start pending\n");
 					vfe2x_ctrl->start_pending = 1;
 					spin_unlock_irqrestore(
 						&vfe2x_ctrl->table_lock,
@@ -1126,9 +1146,36 @@
 				break;
 			case VFE_CMD_STOP:
 				vfestopped = 1;
+				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
+						flags);
+				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+						vfe2x_ctrl->tableack_pending) {
+					CDBG("stop pending\n");
+					vfe2x_ctrl->stop_pending = 1;
+					spin_unlock_irqrestore(
+							&vfe2x_ctrl->table_lock,
+							flags);
+					return 0;
+				}
+				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
+						flags);
 				vfe2x_ctrl->vfe_started = 0;
 				goto config_send;
-
+			case VFE_CMD_UPDATE:
+				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
+						flags);
+				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
+						vfe2x_ctrl->tableack_pending) {
+					CDBG("update pending\n");
+					vfe2x_ctrl->update_pending = 1;
+					spin_unlock_irqrestore(
+							&vfe2x_ctrl->table_lock,
+							flags);
+					return 0;
+				}
+				spin_unlock_irqrestore(&vfe2x_ctrl->table_lock,
+						flags);
+				goto config_send;
 			default:
 				break;
 			}
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
index 90237bd..2b77159 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
@@ -97,6 +97,8 @@
 	struct vfe_cmd_start start_cmd;
 	uint32_t start_pending;
 	uint32_t vfe_started;
+	uint32_t stop_pending;
+	uint32_t update_pending;
 
 	/* v4l2 subdev */
 	struct v4l2_subdev subdev;
diff --git a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
index 4373e22..99e96f0 100644
--- a/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov7692_qrd_v4l2.c
@@ -597,6 +597,22 @@
 	return rc;
 }
 
+static int32_t ov7692_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
+		uint16_t gain, uint32_t line)
+{
+	CDBG("ov7692_write_exp_gain : Not supported\n");
+	return 0;
+}
+
+int32_t ov7692_sensor_set_fps(struct msm_sensor_ctrl_t *s_ctrl,
+		struct fps_cfg *fps)
+{
+	CDBG("ov7692_sensor_set_fps: Not supported\n");
+	return 0;
+}
+
+
+
 static void ov7692_sw_reset(struct msm_sensor_ctrl_t *s_ctrl)
 {
 
@@ -671,7 +687,7 @@
 	.sensor_stop_stream = msm_sensor_stop_stream,
 	.sensor_group_hold_on = msm_sensor_group_hold_on,
 	.sensor_group_hold_off = msm_sensor_group_hold_off,
-	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_set_fps = ov7692_sensor_set_fps,
 	.sensor_setting = msm_sensor_setting3,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
@@ -679,6 +695,8 @@
 	.sensor_config = msm_sensor_config,
 	.sensor_power_up = ov7692_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
+	.sensor_write_exp_gain = ov7692_write_exp_gain,
+	.sensor_write_snapshot_exp_gain = ov7692_write_exp_gain,
 };
 
 static struct msm_sensor_reg_t ov7692_regs = {
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 66b98a1..68395e3 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -439,6 +439,7 @@
 	PLDO("8917_l33",     "8917_l33_pc", 0x0C6, 0x0C7, LDO_150),
 	PLDO("8917_l34",     "8917_l34_pc", 0x0D2, 0x0D3, LDO_150),
 	PLDO("8917_l35",     "8917_l35_pc", 0x0D4, 0x0D5, LDO_300),
+	PLDO("8917_l36",     "8917_l36_pc", 0x0A9, 0x0AA, LDO_50),
 
 	/*    name          ctrl */
 	BOOST("8917_boost", 0x04B),
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 4634e75..93aacef 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1517,7 +1517,7 @@
 	if (!mmc_card_mmc(card))
 		return 0;
 
-	if (card->ext_csd.boot_size) {
+	if (card->ext_csd.boot_size && mmc_boot_partition_access(card->host)) {
 		ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT0,
 					 card->ext_csd.boot_size >> 9,
 					 true,
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index f20ae4b..c4613ba 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -2228,6 +2228,11 @@
 {
 	unsigned int sel_clk = -1;
 
+	if (req_clk < msmsdcc_get_min_sup_clk_rate(host)) {
+		sel_clk = msmsdcc_get_min_sup_clk_rate(host);
+		goto out;
+	}
+
 	if (host->plat->sup_clk_table && host->plat->sup_clk_cnt) {
 		unsigned char cnt;
 
@@ -2248,6 +2253,7 @@
 			sel_clk = req_clk;
 	}
 
+out:
 	return sel_clk;
 }
 
@@ -4495,6 +4501,7 @@
 		mmc->caps |= (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
 				MMC_CAP_SET_XPC_180);
 
+	mmc->caps2 |= MMC_CAP2_BOOTPART_NOACC;
 	if (pdev->dev.of_node) {
 		if (of_get_property((&pdev->dev)->of_node,
 					"qcom,sdcc-hs200", NULL))
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 67c8709..0f008b3 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -240,6 +240,8 @@
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 	}
 
+	slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC;
+
 	return 0;
 }
 
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
index 6d12c7e..84fd462 100644
--- a/drivers/spmi/Kconfig
+++ b/drivers/spmi/Kconfig
@@ -30,6 +30,7 @@
 	depends on SPARSE_IRQ
 	depends on ARCH_MSMCOPPER
 	depends on OF_SPMI
+	depends on MSM_QPNP
 	bool "MSM QPNP INT"
 	help
 	  Say 'y' here to include support for the Qualcomm QPNP interrupt
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 91c3123..042eb4f 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -470,7 +470,7 @@
 	}
 
 bind_config:
-	for (i = 0; i < ports; i++) { 
+	for (i = 0; i < ports; i++) {
 		err = gser_bind_config(c, i);
 		if (err) {
 			pr_err("serial: bind_config failed for port %d", i);
@@ -989,6 +989,31 @@
 	NULL
 };
 
+static void android_cleanup_functions(struct android_usb_function **functions)
+{
+	struct android_usb_function *f;
+	struct device_attribute **attrs;
+	struct device_attribute *attr;
+
+	while (*functions) {
+		f = *functions++;
+
+		if (f->dev) {
+			device_destroy(android_class, f->dev->devt);
+			kfree(f->dev_name);
+		} else
+			continue;
+
+		if (f->cleanup)
+			f->cleanup(f);
+
+		attrs = f->attributes;
+		if (attrs) {
+			while ((attr = *attrs++))
+				device_remove_file(f->dev, attr);
+		}
+	}
+}
 
 static int android_init_functions(struct android_usb_function **functions,
 				  struct usb_composite_dev *cdev)
@@ -998,16 +1023,21 @@
 	struct device_attribute **attrs;
 	struct device_attribute *attr;
 	int err = 0;
-	int index = 0;
+	int index = 1; /* index 0 is for android0 device */
 
 	for (; (f = *functions++); index++) {
 		f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
+		if (!f->dev_name) {
+			err = -ENOMEM;
+			goto err_out;
+		}
 		f->dev = device_create(android_class, dev->dev,
 				MKDEV(0, index), f, f->dev_name);
 		if (IS_ERR(f->dev)) {
 			pr_err("%s: Failed to create dev %s", __func__,
 							f->dev_name);
 			err = PTR_ERR(f->dev);
+			f->dev = NULL;
 			goto err_create;
 		}
 
@@ -1016,7 +1046,7 @@
 			if (err) {
 				pr_err("%s: Failed to init %s", __func__,
 								f->name);
-				goto err_out;
+				goto err_init;
 			}
 		}
 
@@ -1028,35 +1058,26 @@
 		if (err) {
 			pr_err("%s: Failed to create function %s attributes",
 					__func__, f->name);
-			goto err_out;
+			goto err_attrs;
 		}
 	}
 	return 0;
 
-err_out:
+err_attrs:
+	for (attr = *(attrs -= 2); attrs != f->attributes; attr = *(attrs--))
+		device_remove_file(f->dev, attr);
+	if (f->cleanup)
+		f->cleanup(f);
+err_init:
 	device_destroy(android_class, f->dev->devt);
 err_create:
+	f->dev = NULL;
 	kfree(f->dev_name);
+err_out:
+	android_cleanup_functions(dev->functions);
 	return err;
 }
 
-static void android_cleanup_functions(struct android_usb_function **functions)
-{
-	struct android_usb_function *f;
-
-	while (*functions) {
-		f = *functions++;
-
-		if (f->dev) {
-			device_destroy(android_class, f->dev->devt);
-			kfree(f->dev_name);
-		}
-
-		if (f->cleanup)
-			f->cleanup(f);
-	}
-}
-
 static int
 android_bind_enabled_functions(struct android_dev *dev,
 			       struct usb_configuration *c)
@@ -1393,6 +1414,9 @@
 {
 	struct android_dev *dev = _android_dev;
 
+	manufacturer_string[0] = '\0';
+	product_string[0] = '\0';
+	serial_string[0] = '0';
 	cancel_work_sync(&dev->work);
 	android_cleanup_functions(dev->functions);
 	return 0;
@@ -1502,15 +1526,29 @@
 {
 	struct android_usb_platform_data *pdata = pdev->dev.platform_data;
 	struct android_dev *dev = _android_dev;
+	int ret = 0;
 
 	dev->pdata = pdata;
 
+	ret = usb_composite_probe(&android_usb_driver, android_bind);
+	if (ret) {
+		pr_err("%s(): Failed to register android "
+				 "composite driver\n", __func__);
+	}
+
+	return ret;
+}
+
+static int android_remove(struct platform_device *pdev)
+{
+	usb_composite_unregister(&android_usb_driver);
 	return 0;
 }
 
 static struct platform_driver android_platform_driver = {
-	.probe = android_probe,
 	.driver = { .name = "android_usb"},
+	.probe = android_probe,
+	.remove = android_remove,
 };
 
 static int __init init(void)
@@ -1550,13 +1588,7 @@
 				 "platform driver\n", __func__);
 		goto err_probe;
 	}
-	ret = usb_composite_probe(&android_usb_driver, android_bind);
-	if (ret) {
-		pr_err("%s(): Failed to register android"
-				 "composite driver\n", __func__);
-		platform_driver_unregister(&android_platform_driver);
-		goto err_probe;
-	}
+
 	return ret;
 
 err_probe:
@@ -1570,9 +1602,10 @@
 
 static void __exit cleanup(void)
 {
-	usb_composite_unregister(&android_usb_driver);
-	class_destroy(android_class);
+	platform_driver_unregister(&android_platform_driver);
+	android_destroy_device(_android_dev);
 	kfree(_android_dev);
+	class_destroy(android_class);
 	_android_dev = NULL;
 }
 module_exit(cleanup);
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c
index fac777c..eb727b8 100644
--- a/drivers/usb/gadget/ci13xxx_msm.c
+++ b/drivers/usb/gadget/ci13xxx_msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,12 @@
 
 #define MSM_USB_BASE	(udc->regs)
 
+struct ci13xxx_udc_context {
+	int irq;
+	void __iomem *regs;
+};
+static struct ci13xxx_udc_context _udc_ctxt;
+
 static irqreturn_t msm_udc_irq(int irq, void *data)
 {
 	return udc_irq();
@@ -56,8 +62,6 @@
 static int ci13xxx_msm_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	void __iomem *regs;
-	int irq;
 	int ret;
 
 	dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n");
@@ -68,26 +72,27 @@
 		return -ENXIO;
 	}
 
-	regs = ioremap(res->start, resource_size(res));
-	if (!regs) {
+	_udc_ctxt.regs = ioremap(res->start, resource_size(res));
+	if (!_udc_ctxt.regs) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		return -ENOMEM;
 	}
 
-	ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs);
+	ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, _udc_ctxt.regs);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "udc_probe failed\n");
 		goto iounmap;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
+	_udc_ctxt.irq = platform_get_irq(pdev, 0);
+	if (_udc_ctxt.irq < 0) {
 		dev_err(&pdev->dev, "IRQ not found\n");
 		ret = -ENXIO;
 		goto udc_remove;
 	}
 
-	ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev);
+	ret = request_irq(_udc_ctxt.irq, msm_udc_irq, IRQF_SHARED, pdev->name,
+					  pdev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "request_irq failed\n");
 		goto udc_remove;
@@ -101,14 +106,24 @@
 udc_remove:
 	udc_remove();
 iounmap:
-	iounmap(regs);
+	iounmap(_udc_ctxt.regs);
 
 	return ret;
 }
 
+int ci13xxx_msm_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+	free_irq(_udc_ctxt.irq, pdev);
+	udc_remove();
+	iounmap(_udc_ctxt.regs);
+	return 0;
+}
+
 static struct platform_driver ci13xxx_msm_driver = {
 	.probe = ci13xxx_msm_probe,
 	.driver = { .name = "msm_hsusb", },
+	.remove = ci13xxx_msm_remove,
 };
 
 static int __init ci13xxx_msm_init(void)
@@ -116,3 +131,11 @@
 	return platform_driver_register(&ci13xxx_msm_driver);
 }
 module_init(ci13xxx_msm_init);
+
+static void __exit ci13xxx_msm_exit(void)
+{
+	platform_driver_unregister(&ci13xxx_msm_driver);
+}
+module_exit(ci13xxx_msm_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
index 12b6774..3736367 100644
--- a/drivers/usb/gadget/ci13xxx_msm_hsic.c
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -767,3 +767,4 @@
 module_init(msm_hsic_peripheral_init);
 module_exit(msm_hsic_peripheral_exit);
 
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index c9d9c07..4f2946c 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1634,6 +1634,8 @@
 int usb_composite_probe(struct usb_composite_driver *driver,
 			       int (*bind)(struct usb_composite_dev *cdev))
 {
+	int retval;
+
 	if (!driver || !driver->dev || !bind || composite)
 		return -EINVAL;
 
@@ -1648,7 +1650,10 @@
 	composite = driver;
 	composite_gadget_bind = bind;
 
-	return usb_gadget_probe_driver(&composite_driver, composite_bind);
+	retval = usb_gadget_probe_driver(&composite_driver, composite_bind);
+	if (retval)
+		composite = NULL;
+	return retval;
 }
 
 /**
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index c85d499..0e619e6 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -495,7 +495,17 @@
 	}
 
 	/* wait for a request to complete */
-	ret = wait_event_interruptible(dev->read_wq, dev->rx_done);
+	ret = wait_event_interruptible(dev->read_wq,
+				dev->rx_done || dev->state != STATE_BUSY);
+	if (dev->state == STATE_CANCELED) {
+		r = -ECANCELED;
+		if (!dev->rx_done)
+			usb_ep_dequeue(dev->ep_out, req);
+		spin_lock_irq(&dev->lock);
+		dev->state = STATE_CANCELED;
+		spin_unlock_irq(&dev->lock);
+		goto done;
+	}
 	if (ret < 0) {
 		r = ret;
 		usb_ep_dequeue(dev->ep_out, req);
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index 8671669..0256a75 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -108,14 +108,17 @@
 	void *buf;
 	unsigned long flags;
 
-	while (1) {
+	spin_lock_irqsave(&port->port_lock, flags);
+	while (c->ch) {
 		sz = smd_cur_packet_size(c->ch);
-		if (sz == 0)
+		if (sz <= 0)
 			break;
 
 		if (smd_read_avail(c->ch) < sz)
 			break;
 
+		spin_unlock_irqrestore(&port->port_lock, flags);
+
 		buf = kmalloc(sz, GFP_KERNEL);
 		if (!buf)
 			return;
@@ -130,8 +133,8 @@
 			c->to_host++;
 		}
 		kfree(buf);
-		spin_unlock_irqrestore(&port->port_lock, flags);
 	}
+	spin_unlock_irqrestore(&port->port_lock, flags);
 }
 
 static void grmnet_ctrl_smd_write_w(struct work_struct *w)
@@ -143,7 +146,7 @@
 	int ret;
 
 	spin_lock_irqsave(&port->port_lock, flags);
-	while (1) {
+	while (c->ch) {
 		if (list_empty(&c->tx_q))
 			break;
 
diff --git a/drivers/usb/gadget/u_smd.c b/drivers/usb/gadget/u_smd.c
index e74b2e1..a5ceaff 100644
--- a/drivers/usb/gadget/u_smd.c
+++ b/drivers/usb/gadget/u_smd.c
@@ -209,6 +209,7 @@
 static void gsmd_rx_push(struct work_struct *w)
 {
 	struct gsmd_port *port = container_of(w, struct gsmd_port, push);
+	struct smd_port_info *pi = port->pi;
 	struct list_head *q;
 
 	pr_debug("%s: port:%p port#%d", __func__, port, port->port_num);
@@ -216,10 +217,9 @@
 	spin_lock_irq(&port->port_lock);
 
 	q = &port->read_queue;
-	while (!list_empty(q)) {
+	while (pi->ch && !list_empty(q)) {
 		struct usb_request *req;
 		int avail;
-		struct smd_port_info *pi = port->pi;
 
 		req = list_first_entry(q, struct usb_request, list);
 
@@ -296,21 +296,24 @@
 {
 	struct gsmd_port *port = container_of(w, struct gsmd_port, pull);
 	struct list_head *pool = &port->write_pool;
+	struct smd_port_info *pi = port->pi;
+	struct usb_ep *in;
 
 	pr_debug("%s: port:%p port#%d pool:%p\n", __func__,
 			port, port->port_num, pool);
 
+	spin_lock_irq(&port->port_lock);
+
 	if (!port->port_usb) {
 		pr_debug("%s: usb is disconnected\n", __func__);
+		spin_unlock_irq(&port->port_lock);
 		gsmd_read_pending(port);
 		return;
 	}
 
-	spin_lock_irq(&port->port_lock);
-	while (!list_empty(pool)) {
+	in = port->port_usb->in;
+	while (pi->ch && !list_empty(pool)) {
 		struct usb_request *req;
-		struct usb_ep *in = port->port_usb->in;
-		struct smd_port_info *pi = port->pi;
 		int avail;
 		int ret;
 
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 795e7a8..2d43a78 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -24,7 +24,6 @@
 
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-#include <linux/irq.h>
 #include <linux/err.h>
 #include <linux/wakelock.h>
 #include <linux/pm_runtime.h>
@@ -55,6 +54,7 @@
 	struct wake_lock	wlock;
 	int			peripheral_status_irq;
 	int			wakeup_irq;
+	bool			wakeup_irq_enabled;
 };
 
 static inline struct msm_hsic_hcd *hcd_to_hsic(struct usb_hcd *hcd)
@@ -750,6 +750,12 @@
 
 	dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt\n", __func__);
 
+	if (mehci->wakeup_irq_enabled) {
+		mehci->wakeup_irq_enabled = 0;
+		disable_irq_wake(irq);
+		disable_irq_nosync(irq);
+	}
+
 	return IRQ_HANDLED;
 }
 
@@ -878,7 +884,6 @@
 				"msm_hsic_wakeup", mehci);
 		if (!ret) {
 			disable_irq_nosync(mehci->wakeup_irq);
-			enable_irq_wake(mehci->wakeup_irq);
 		} else {
 			dev_err(&pdev->dev, "request_irq(%d) failed: %d\n",
 					mehci->wakeup_irq, ret);
@@ -923,8 +928,10 @@
 
 	if (mehci->peripheral_status_irq)
 		free_irq(mehci->peripheral_status_irq, mehci);
+
 	if (mehci->wakeup_irq) {
-		disable_irq_wake(mehci->wakeup_irq);
+		if (mehci->wakeup_irq_enabled)
+			disable_irq_wake(mehci->wakeup_irq);
 		free_irq(mehci->wakeup_irq, mehci);
 	}
 
@@ -959,7 +966,22 @@
 		enable_irq_wake(hcd->irq);
 
 	return msm_hsic_suspend(mehci);
+}
 
+static int msm_hsic_pm_suspend_noirq(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
+
+	dev_dbg(dev, "ehci-msm-hsic PM suspend_noirq\n");
+
+	if (device_may_wakeup(dev) && !mehci->wakeup_irq_enabled) {
+		enable_irq(mehci->wakeup_irq);
+		enable_irq_wake(mehci->wakeup_irq);
+		mehci->wakeup_irq_enabled = 1;
+	}
+
+	return 0;
 }
 
 static int msm_hsic_pm_resume(struct device *dev)
@@ -973,6 +995,12 @@
 	if (device_may_wakeup(dev))
 		disable_irq_wake(hcd->irq);
 
+	if (mehci->wakeup_irq_enabled) {
+		mehci->wakeup_irq_enabled = 0;
+		disable_irq_wake(mehci->wakeup_irq);
+		disable_irq_nosync(mehci->wakeup_irq);
+	}
+
 	ret = msm_hsic_resume(mehci);
 	if (ret)
 		return ret;
@@ -1016,6 +1044,7 @@
 #ifdef CONFIG_PM
 static const struct dev_pm_ops msm_hsic_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(msm_hsic_pm_suspend, msm_hsic_pm_resume)
+	.suspend_noirq = msm_hsic_pm_suspend_noirq,
 	SET_RUNTIME_PM_OPS(msm_hsic_runtime_suspend, msm_hsic_runtime_resume,
 				msm_hsic_runtime_idle)
 };
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 4318efb..fc43a0d 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -82,7 +82,7 @@
 	if (!init)
 		goto disable_reg;
 
-	mhcd->hsusb_vddcx = regulator_get(mhcd->dev, "HSUSB_VDDCX");
+	mhcd->hsusb_vddcx = devm_regulator_get(mhcd->dev, "HSUSB_VDDCX");
 	if (IS_ERR(mhcd->hsusb_vddcx)) {
 		dev_err(mhcd->dev, "unable to get ehci vddcx\n");
 		return PTR_ERR(mhcd->hsusb_vddcx);
@@ -94,7 +94,7 @@
 	if (ret) {
 		dev_err(mhcd->dev, "unable to set the voltage"
 				"for ehci vddcx\n");
-		goto reg_set_voltage_err;
+		return ret;
 	}
 
 	ret = regulator_set_optimum_mode(mhcd->hsusb_vddcx,
@@ -120,9 +120,6 @@
 reg_optimum_mode_err:
 	regulator_set_voltage(mhcd->hsusb_vddcx, 0,
 				HSUSB_PHY_VDD_DIG_VOL_MIN);
-reg_set_voltage_err:
-	regulator_put(mhcd->hsusb_vddcx);
-
 	return ret;
 
 }
@@ -134,7 +131,7 @@
 	if (!init)
 		goto put_1p8;
 
-	mhcd->hsusb_3p3 = regulator_get(mhcd->dev, "HSUSB_3p3");
+	mhcd->hsusb_3p3 = devm_regulator_get(mhcd->dev, "HSUSB_3p3");
 	if (IS_ERR(mhcd->hsusb_3p3)) {
 		dev_err(mhcd->dev, "unable to get hsusb 3p3\n");
 		return PTR_ERR(mhcd->hsusb_3p3);
@@ -145,9 +142,9 @@
 	if (rc) {
 		dev_err(mhcd->dev, "unable to set voltage level for"
 				"hsusb 3p3\n");
-		goto put_3p3;
+		return rc;
 	}
-	mhcd->hsusb_1p8 = regulator_get(mhcd->dev, "HSUSB_1p8");
+	mhcd->hsusb_1p8 = devm_regulator_get(mhcd->dev, "HSUSB_1p8");
 	if (IS_ERR(mhcd->hsusb_1p8)) {
 		dev_err(mhcd->dev, "unable to get hsusb 1p8\n");
 		rc = PTR_ERR(mhcd->hsusb_1p8);
@@ -165,11 +162,8 @@
 
 put_1p8:
 	regulator_set_voltage(mhcd->hsusb_1p8, 0, HSUSB_PHY_1P8_VOL_MAX);
-	regulator_put(mhcd->hsusb_1p8);
 put_3p3_lpm:
 	regulator_set_voltage(mhcd->hsusb_3p3, 0, HSUSB_PHY_3P3_VOL_MAX);
-put_3p3:
-	regulator_put(mhcd->hsusb_3p3);
 
 	return rc;
 }
@@ -273,13 +267,12 @@
 	pdata = mhcd->dev->platform_data;
 
 	if (!init) {
-		regulator_put(mhcd->vbus);
 		if (pdata && pdata->dock_connect_irq)
 			free_irq(pdata->dock_connect_irq, mhcd);
 		return rc;
 	}
 
-	mhcd->vbus = regulator_get(mhcd->dev, "vbus");
+	mhcd->vbus = devm_regulator_get(mhcd->dev, "vbus");
 	if (IS_ERR(mhcd->vbus)) {
 		pr_err("Unable to get vbus\n");
 		return -ENODEV;
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index a064d11..606d349 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -249,6 +249,20 @@
 	select FB_MSM_LCDC_PANEL
 	default n
 
+config FB_MSM_LCDC_TRULY_HVGA_IPS3P2335
+        bool
+        select FB_MSM_LCDC_PANEL
+        default n
+
+config FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL
+        depends on FB_MSM_LCDC_HW
+        bool "LCDC Truly HVGA PT Panel"
+        select FB_MSM_LCDC_TRULY_HVGA_IPS3P2335
+        default n
+        ---help---
+        Support for LCDC Truly HVGA PT panel
+
+
 config FB_MSM_LCDC_SAMSUNG_OLED_PT
 	bool
 	select FB_MSM_LCDC_PANEL
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index aabe490..e6c869f 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -165,6 +165,7 @@
 obj-$(CONFIG_FB_MSM_LVDS_CHIMEI_WXGA) += lvds_chimei_wxga.o
 obj-$(CONFIG_FB_MSM_HDMI_MSM_PANEL) += hdmi_msm.o
 obj-$(CONFIG_FB_MSM_EXT_INTERFACE_COMMON) += external_common.o
+obj-$(CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335) += lcdc_truly_ips3p2335.o
 
 obj-$(CONFIG_FB_MSM_TVOUT) += tvout_msm.o
 
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index a056328..7c5a653 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4142,6 +4142,19 @@
 	return 0;
 }
 
+static int hdmi_msm_power_ctrl(boolean enable)
+{
+	if (!external_common_state->hpd_feature_on)
+		return 0;
+
+	if (enable)
+		hdmi_msm_hpd_on(true);
+	else
+		hdmi_msm_hpd_off();
+
+	return 0;
+}
+
 static int hdmi_msm_power_on(struct platform_device *pdev)
 {
 	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
@@ -4163,7 +4176,7 @@
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
 
 	changed = hdmi_common_get_video_format_from_drv_data(mfd);
-	if (!external_common_state->hpd_feature_on) {
+	if (!external_common_state->hpd_feature_on || mfd->ref_cnt) {
 		int rc = hdmi_msm_hpd_on(true);
 		DEV_INFO("HPD: panel power without 'hpd' feature on\n");
 		if (rc) {
@@ -4198,6 +4211,8 @@
  */
 static int hdmi_msm_power_off(struct platform_device *pdev)
 {
+	struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
+
 	if (!hdmi_msm_state->hdmi_app_clk)
 		return -ENODEV;
 
@@ -4223,7 +4238,7 @@
 	hdmi_msm_hpd_on(true);
 
 	mutex_lock(&external_common_state_hpd_mutex);
-	if (!external_common_state->hpd_feature_on)
+	if (!external_common_state->hpd_feature_on || mfd->ref_cnt)
 		hdmi_msm_hpd_off();
 	mutex_unlock(&external_common_state_hpd_mutex);
 
@@ -4497,6 +4512,7 @@
 static struct msm_fb_panel_data hdmi_msm_panel_data = {
 	.on = hdmi_msm_power_on,
 	.off = hdmi_msm_power_off,
+	.power_ctrl = hdmi_msm_power_ctrl,
 };
 
 static struct platform_device this_device = {
diff --git a/drivers/video/msm/lcdc_truly_ips3p2335.c b/drivers/video/msm/lcdc_truly_ips3p2335.c
new file mode 100644
index 0000000..838c083
--- /dev/null
+++ b/drivers/video/msm/lcdc_truly_ips3p2335.c
@@ -0,0 +1,305 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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/delay.h>
+#include <linux/module.h>
+#include <mach/gpio.h>
+#include <mach/pmic.h>
+#include "msm_fb.h"
+
+static int prev_bl = 17;
+
+static int spi_cs;
+static int spi_sclk;
+static int spi_mosi;
+static int gpio_backlight_en;
+static int gpio_display_reset;
+
+struct truly_state_type {
+	boolean disp_initialized;
+	boolean display_on;
+	boolean disp_powered_up;
+};
+
+static struct truly_state_type truly_state = { 0 };
+static struct msm_panel_common_pdata *lcdc_truly_pdata;
+
+static char init_item_v1[] = { 0xff, 0x83, 0x57, };
+static char init_item_v2[] = { 0x03, };
+static char init_item_v3[] = { 0x00, 0x13, 0x1C, 0x1C, 0x83, 0x48, };
+static char init_item_v4[] = { 0x43, 0x06, 0x06, 0x06, };
+static char init_item_v5[] = { 0x53, };
+static char init_item_v6[] = { 0x02, 0x40, 0x00, 0x2a, 0x2a, 0x0d, 0x3f, };
+static char init_item_v7[] = { 0x70, 0x50, 0x01, 0x3c, 0xe8, 0x08, };
+static char init_item_v8[] = { 0x17, 0x0f, };
+static char init_item_v9[] = { 0x60};
+static char init_item_v10[] = { 0x00, 0x13, 0x1a, 0x29, 0x2d, 0x41, 0x49,
+				0x52, 0x48, 0x41, 0x3c, 0x33, 0x30, 0x1c,
+				0x19, 0x03, 0x00, 0x13, 0x1a, 0x29, 0x2d,
+				0x41, 0x49, 0x52, 0x48, 0x41, 0x3c, 0x33,
+				0x31, 0x1c, 0x19, 0x03, 0x00, 0x01,
+				};
+static char init_item_v11[] = { 0x40, };
+
+static inline void truly_spi_write_byte(char dc, uint8 data)
+{
+	uint32 bit;
+	int bnum;
+
+	gpio_set_value_cansleep(spi_sclk, 0); /* clk low */
+	/* dc: 0 for command, 1 for parameter */
+	gpio_set_value_cansleep(spi_mosi, dc);
+	udelay(1);	/* at least 20 ns */
+	gpio_set_value_cansleep(spi_sclk, 1); /* clk high */
+	udelay(1);	/* at least 20 ns */
+	bnum = 8;	/* 8 data bits */
+	bit = 0x80;
+	while (bnum) {
+		gpio_set_value_cansleep(spi_sclk, 0); /* clk low */
+		if (data & bit)
+			gpio_set_value_cansleep(spi_mosi, 1);
+		else
+			gpio_set_value_cansleep(spi_mosi, 0);
+		udelay(1);
+		gpio_set_value_cansleep(spi_sclk, 1); /* clk high */
+		udelay(1);
+		bit >>= 1;
+		bnum--;
+	}
+}
+
+static inline int truly_spi_write(char cmd, char *data, int num)
+{
+	int i;
+
+	gpio_set_value_cansleep(spi_cs, 0);	/* cs low */
+	/* command byte first */
+	truly_spi_write_byte(0, cmd);
+	/* followed by parameter bytes */
+	for (i = 0; i < num; i++) {
+		if (data)
+			truly_spi_write_byte(1, data[i]);
+	}
+	gpio_set_value_cansleep(spi_mosi, 1);	/* mosi high */
+	gpio_set_value_cansleep(spi_cs, 1);	/* cs high */
+	udelay(10);
+	return 0;
+}
+
+static void spi_pin_assign(void)
+{
+	/* Setting the Default GPIO's */
+	spi_mosi	= *(lcdc_truly_pdata->gpio_num);
+	spi_sclk	= *(lcdc_truly_pdata->gpio_num + 1);
+	spi_cs		= *(lcdc_truly_pdata->gpio_num + 2);
+	gpio_backlight_en = *(lcdc_truly_pdata->gpio_num + 3);
+	gpio_display_reset = *(lcdc_truly_pdata->gpio_num + 4);
+	pr_debug("spi_mosi:%d spi_sclk:%d spi_cs:%d backlight:%d reset:%d\n",
+		spi_mosi, spi_sclk, spi_cs, gpio_backlight_en,
+		gpio_display_reset);
+
+}
+
+static void truly_disp_powerup(void)
+{
+	/* Reset the hardware first */
+	/* Include DAC power up implementation here */
+	if (!truly_state.disp_powered_up && !truly_state.display_on)
+		truly_state.disp_powered_up = TRUE;
+}
+
+static void truly_disp_reginit(void)
+{
+	pr_debug("%s disp_powered_up:%d display_on:%d\n", __func__,
+			truly_state.disp_powered_up, truly_state.display_on);
+	if (truly_state.disp_powered_up && !truly_state.display_on) {
+		gpio_set_value_cansleep(spi_cs, 1);	/* cs high */
+
+		truly_spi_write(0xb9, init_item_v1, sizeof(init_item_v1));
+		msleep(20);
+		truly_spi_write(0xcc, init_item_v2, sizeof(init_item_v2));
+		truly_spi_write(0xb1, init_item_v3, sizeof(init_item_v3));
+		truly_spi_write(0xb3, init_item_v4, sizeof(init_item_v4));
+		truly_spi_write(0xb6, init_item_v5, sizeof(init_item_v5));
+		truly_spi_write(0xb4, init_item_v6, sizeof(init_item_v6));
+		truly_spi_write(0xc0, init_item_v7, sizeof(init_item_v7));
+		truly_spi_write(0xe3, init_item_v8, sizeof(init_item_v8));
+		truly_spi_write(0x3a, init_item_v9, sizeof(init_item_v9));
+		truly_spi_write(0xe0, init_item_v10, sizeof(init_item_v10));
+		truly_spi_write(0x36, init_item_v11, sizeof(init_item_v11));
+		truly_spi_write(0x11, NULL, 0);
+		msleep(150);
+		truly_spi_write(0x29, NULL, 0);
+		msleep(25);
+
+		truly_state.display_on = TRUE;
+	}
+}
+
+static int lcdc_truly_panel_on(struct platform_device *pdev)
+{
+	/* Configure reset GPIO that drives DAC */
+	if (lcdc_truly_pdata->panel_config_gpio)
+		lcdc_truly_pdata->panel_config_gpio(1);
+	gpio_set_value_cansleep(gpio_display_reset, 1);
+	truly_disp_powerup();
+	truly_disp_reginit();
+	truly_state.disp_initialized = TRUE;
+	return 0;
+}
+
+static int lcdc_truly_panel_off(struct platform_device *pdev)
+{
+	if (truly_state.disp_powered_up && truly_state.display_on) {
+		/* Main panel power off (Pull down reset) */
+		gpio_set_value_cansleep(gpio_display_reset, 0);
+		truly_state.display_on = FALSE;
+		truly_state.disp_initialized = FALSE;
+	}
+	return 0;
+}
+
+static void lcdc_truly_set_backlight(struct msm_fb_data_type *mfd)
+{
+	int step = 0, i = 0;
+	unsigned long flags;
+	int bl_level = mfd->bl_level;
+
+	/* real backlight level, 1 - max, 16 - min, 17 - off */
+	bl_level = 17 - bl_level;
+
+	if (bl_level > prev_bl) {
+		step = bl_level - prev_bl;
+		if (bl_level == 17)
+			step--;
+	} else if (bl_level < prev_bl) {
+		step = bl_level + 16 - prev_bl;
+	} else {
+		pr_info("%s: no change\n", __func__);
+		return;
+	}
+
+	if (bl_level == 17) {
+		/* turn off backlight */
+		gpio_set_value(gpio_backlight_en, 0);
+	} else {
+		local_irq_save(flags);
+
+		if (prev_bl == 17) {
+			/* turn on backlight */
+			gpio_set_value(gpio_backlight_en, 1);
+			udelay(30);
+		}
+
+		/* adjust backlight level */
+		for (i = 0; i < step; i++) {
+			gpio_set_value(gpio_backlight_en, 0);
+			udelay(1);
+			gpio_set_value(gpio_backlight_en, 1);
+			udelay(1);
+		}
+
+		local_irq_restore(flags);
+	}
+	msleep(20);
+	prev_bl = bl_level;
+
+	return;
+}
+
+static int __devinit truly_probe(struct platform_device *pdev)
+{
+
+	if (pdev->id == 0) {
+		lcdc_truly_pdata = pdev->dev.platform_data;
+
+		if (!lcdc_truly_pdata)
+			pr_err("%s pdata is null\n", __func__);
+
+		spi_pin_assign();
+		return 0;
+	}
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = truly_probe,
+	.driver = {
+		.name   = "lcdc_truly_hvga_ips3p2335_pt",
+	},
+};
+
+static struct msm_fb_panel_data truly_panel_data = {
+	.on = lcdc_truly_panel_on,
+	.off = lcdc_truly_panel_off,
+	.set_backlight = lcdc_truly_set_backlight,
+};
+
+static struct platform_device this_device = {
+	.name   = "lcdc_truly_hvga_ips3p2335_pt",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &truly_panel_data,
+	}
+};
+
+static int __init lcdc_truly_panel_init(void)
+{
+	int ret;
+	struct msm_panel_info *pinfo;
+
+	ret = msm_fb_detect_client("lcdc_truly_hvga_ips3p2335_pt");
+	if (ret)
+		return 0;
+
+	ret = platform_driver_register(&this_driver);
+	if (ret) {
+		pr_err("%s() driver registration failed", __func__);
+		return ret;
+	}
+
+	pinfo = &truly_panel_data.panel_info;
+	pinfo->xres = 320;
+	pinfo->yres = 480;
+	MSM_FB_SINGLE_MODE_PANEL(pinfo);
+	pinfo->type = LCDC_PANEL;
+	pinfo->pdest = DISPLAY_1;
+	pinfo->wait_cycle = 0;
+	pinfo->bpp = 18;
+	pinfo->fb_num = 2;
+	/* 10Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */
+	pinfo->clk_rate = 10240000;
+	pinfo->bl_max = 16;
+	pinfo->bl_min = 1;
+
+	pinfo->lcdc.h_back_porch = 16;		/* hsw = 8 + hbp=16 */
+	pinfo->lcdc.h_front_porch = 4;
+	pinfo->lcdc.h_pulse_width = 8;
+	pinfo->lcdc.v_back_porch = 7;		/* vsw=1 + vbp = 7 */
+	pinfo->lcdc.v_front_porch = 3;
+	pinfo->lcdc.v_pulse_width = 1;
+	pinfo->lcdc.border_clr = 0;		/* blk */
+	pinfo->lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo->lcdc.hsync_skew = 0;
+
+	ret = platform_device_register(&this_device);
+	if (ret) {
+		pr_err("%s not able to register the device\n", __func__);
+		platform_driver_unregister(&this_driver);
+	}
+	return ret;
+}
+
+device_initcall(lcdc_truly_panel_init);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index b69fe6e..a3b03b8 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1360,44 +1360,63 @@
 		}
 	}
 
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	if (ctrl->mixer_cfg[mixer] != cfg[mixer]) {
-		if (mixer <= MDP4_MIXER1) {
+		if ((ctrl->mixer_cfg[MDP4_MIXER0] != cfg[MDP4_MIXER0]) ||
+		    (ctrl->mixer_cfg[MDP4_MIXER1] != cfg[MDP4_MIXER1])) {
 			off = 0x10100;
 			if (ctrl->mixer_cfg[MDP4_MIXER0] != cfg[MDP4_MIXER0]) {
 				flush_bits |= 0x1;
 				ctrl->mixer_cfg[MDP4_MIXER0] = cfg[MDP4_MIXER0];
+
+				if ((ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) ||
+				    (ctrl->panel_mode & MDP4_PANEL_LCDC))
+					pull_mode = 1;
 			}
 			if (ctrl->mixer_cfg[MDP4_MIXER1] != cfg[MDP4_MIXER1]) {
 				flush_bits |= 0x2;
 				ctrl->mixer_cfg[MDP4_MIXER1] = cfg[MDP4_MIXER1];
+
+				pull_mode = 1;
 			}
+
 			data = cfg[MDP4_MIXER0] | cfg[MDP4_MIXER1];
-		} else {
+
+			pr_debug("%s: mixer=%d data=%x flush=%x\n", __func__,
+			       mixer, data, flush_bits);
+
+			outpdw(MDP_BASE + off, data); /* LAYERMIXER_IN_CFG */
+			if (pull_mode)
+				outpdw(MDP_BASE + 0x18000, flush_bits);
+		}
+
+		if (ctrl->mixer_cfg[MDP4_MIXER2] != cfg[MDP4_MIXER2]) {
+			/* wait for vsync on both pull mode interfaces */
+			if (pull_mode)
+				msleep(20);
+
 			off = 0x100F0;
 			ctrl->mixer_cfg[MDP4_MIXER2] = cfg[MDP4_MIXER2];
 			data = cfg[MDP4_MIXER2];
+
+			pr_debug("%s: mixer=%d data=%x\n", __func__,
+			       mixer, data);
+
+			outpdw(MDP_BASE + off, data); /* LAYERMIXER_IN_CFG */
+		}
+	} else {
+		if (mixer == MDP4_MIXER0) {
+			if ((ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) ||
+			(ctrl->panel_mode & MDP4_PANEL_LCDC))
+				pull_mode = 1;
+		} else if (mixer == MDP4_MIXER1) {
+			pull_mode = 1;
 		}
 
-		pr_debug("%s: mixer=%d data=%x flush=%x\n", __func__,
-		       mixer, data, flush_bits);
-		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-		outpdw(MDP_BASE + off, data); /* MDP_LAYERMIXER_IN_CFG */
-		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+		if (pull_mode)
+			outpdw(MDP_BASE + 0x18000, flush_bits);
 	}
-
-	if (mixer == MDP4_MIXER0) {
-		if ((ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) ||
-		    (ctrl->panel_mode & MDP4_PANEL_LCDC))
-			pull_mode = 1;
-	} else if (mixer == MDP4_MIXER1) {
-		pull_mode = 1;
-	}
-
-	if (pull_mode) {
-		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-		outpdw(MDP_BASE + 0x18000, flush_bits);
-		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
-	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 
 	if (data && pipe_cnt == 1)
 		mdp4_update_perf_level(OVERLAY_PERF_LEVEL4);
diff --git a/drivers/video/msm/msm_dss_io_8x60.c b/drivers/video/msm/msm_dss_io_8x60.c
index 0daf727..6dac6c1 100644
--- a/drivers/video/msm/msm_dss_io_8x60.c
+++ b/drivers/video/msm/msm_dss_io_8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -579,6 +579,14 @@
 
 void hdmi_msm_powerdown_phy(void)
 {
+	/* Assert RESET PHY from controller */
+	HDMI_OUTP_ND(0x02D4, 0x4);
+	udelay(10);
+	/* De-assert RESET PHY from controller */
+	HDMI_OUTP_ND(0x02D4, 0x0);
+	/* Turn off Driver */
+	HDMI_OUTP_ND(0x0308, 0x1F);
+	udelay(10);
 	/* Disable PLL */
 	HDMI_OUTP_ND(0x030C, 0x00);
 	/* Power down PHY */
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index db47a31..1b0dfbe 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -542,10 +542,13 @@
 static int msm_fb_resume_sub(struct msm_fb_data_type *mfd)
 {
 	int ret = 0;
+	struct msm_fb_panel_data *pdata = NULL;
 
 	if ((!mfd) || (mfd->key != MFD_KEY))
 		return 0;
 
+	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;
+
 	/* attach display channel irq if there's any */
 	if (mfd->channel_irq != 0)
 		enable_irq(mfd->channel_irq);
@@ -560,6 +563,9 @@
 				      mfd->op_enable);
 		if (ret)
 			MSM_FB_INFO("msm_fb_resume: can't turn on display!\n");
+	} else {
+		if (pdata->power_ctrl)
+			pdata->power_ctrl(TRUE);
 	}
 
 	return ret;
@@ -795,6 +801,9 @@
 				mfd->panel_power_on = curr_pwr_state;
 
 			mfd->op_enable = TRUE;
+		} else {
+			if (pdata->power_ctrl)
+				pdata->power_ctrl(FALSE);
 		}
 		break;
 	}
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index 903c865..a4072c8 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -188,6 +188,7 @@
 	/* function entry chain */
 	int (*on) (struct platform_device *pdev);
 	int (*off) (struct platform_device *pdev);
+	int (*power_ctrl) (boolean enable);
 	struct platform_device *next;
 	int (*clk_func) (int enable);
 };
diff --git a/include/linux/input/ft5x06_ts.h b/include/linux/input/ft5x06_ts.h
new file mode 100644
index 0000000..b2fb3c4
--- /dev/null
+++ b/include/linux/input/ft5x06_ts.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * FocalTech ft5x06 TouchScreen driver header file.
+ *
+ * Copyright (c) 2010  Focal tech Ltd.
+ * Copyright (c) 2012, Code Aurora Forum. 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 __LINUX_FT5X06_TS_H__
+#define __LINUX_FT5X06_TS_H__
+
+struct ft5x06_ts_platform_data {
+	unsigned long irqflags;
+	u32 x_max;
+	u32 y_max;
+	u32 irq_gpio;
+	u32 reset_gpio;
+	int (*power_init) (bool);
+	int (*power_on) (bool);
+};
+
+#endif
diff --git a/include/linux/mfd/pm8xxx/pm8xxx-adc.h b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
index a572ae3..d2b1cfc 100644
--- a/include/linux/mfd/pm8xxx/pm8xxx-adc.h
+++ b/include/linux/mfd/pm8xxx/pm8xxx-adc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -75,7 +75,6 @@
 	ADC_MPP_1_ATEST_5,
 	ADC_MPP_1_ATEST_6,
 	ADC_MPP_1_ATEST_7,
-	ADC_MPP_1_CHANNEL_NONE,
 	ADC_MPP_2_ATEST_8 = 40,
 	ADC_MPP_2_USB_SNS_DIV20,
 	ADC_MPP_2_DCIN_SNS_DIV20,
@@ -92,7 +91,7 @@
 	ADC_MPP_2_ATEST_5,
 	ADC_MPP_2_ATEST_6,
 	ADC_MPP_2_ATEST_7,
-	ADC_MPP_2_CHANNEL_NONE,
+	ADC_CHANNEL_MAX_NUM,
 };
 
 #define PM8XXX_ADC_PMIC_0	0x0
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index db14e38..46f71a1 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -241,6 +241,7 @@
 
 	unsigned int		caps2;		/* More host capabilities */
 
+#define MMC_CAP2_BOOTPART_NOACC	(1 << 0)	/* Boot partition no access */
 #define MMC_CAP2_CACHE_CTRL	(1 << 1)	/* Allow cache control */
 #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2)	/* Notify poweroff supported */
 #define MMC_CAP2_NO_MULTI_READ	(1 << 3)	/* Multiblock reads don't work */
@@ -475,6 +476,11 @@
 	return host->caps & MMC_CAP_CMD23;
 }
 
+static inline int mmc_boot_partition_access(struct mmc_host *host)
+{
+	return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
+}
+
 #ifdef CONFIG_MMC_CLKGATE
 void mmc_host_clk_hold(struct mmc_host *host);
 void mmc_host_clk_release(struct mmc_host *host);
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index 211d146..381f5c4 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -472,7 +472,8 @@
 	TAVARUA_EVT_NEW_SRCH_LIST,
 	TAVARUA_EVT_NEW_AF_LIST,
 	TAVARUA_EVT_TXRDSDAT,
-	TAVARUA_EVT_TXRDSDONE
+	TAVARUA_EVT_TXRDSDONE,
+	TAVARUA_EVT_RADIO_DISABLED
 };
 
 enum tavarua_region_t {
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 6aeabf9..9b279cc 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -12,6 +12,7 @@
 #include <linux/string.h>
 #include <linux/resume-trace.h>
 #include <linux/workqueue.h>
+#include <linux/hrtimer.h>
 
 #include "power.h"
 
@@ -25,8 +26,11 @@
 
 static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
 
-static struct hrtimer in_ev_timer;
-static int input_processed;
+static void touch_event_fn(struct work_struct *work);
+static DECLARE_WORK(touch_event_struct, touch_event_fn);
+
+static struct hrtimer tc_ev_timer;
+static int tc_ev_processed;
 static ktime_t touch_evt_timer_val;
 
 int register_pm_notifier(struct notifier_block *nb)
@@ -77,7 +81,7 @@
 touch_event_show(struct kobject *kobj,
 		 struct kobj_attribute *attr, char *buf)
 {
-	if (input_processed == 0)
+	if (tc_ev_processed == 0)
 		return snprintf(buf, strnlen("touch_event", MAX_BUF) + 1,
 				"touch_event");
 	else
@@ -91,13 +95,13 @@
 		  const char *buf, size_t n)
 {
 
-	hrtimer_cancel(&in_ev_timer);
-	input_processed = 0;
+	hrtimer_cancel(&tc_ev_timer);
+	tc_ev_processed = 0;
 
 	/* set a timer to notify the userspace to stop processing
 	 * touch event
 	 */
-	hrtimer_start(&in_ev_timer, touch_evt_timer_val, HRTIMER_MODE_REL);
+	hrtimer_start(&tc_ev_timer, touch_evt_timer_val, HRTIMER_MODE_REL);
 
 	/* wakeup the userspace poll */
 	sysfs_notify(kobj, NULL, "touch_event");
@@ -131,11 +135,20 @@
 
 power_attr(touch_event_timer);
 
-static enum hrtimer_restart input_event_stop(struct hrtimer *hrtimer)
+static void touch_event_fn(struct work_struct *work)
 {
 	/* wakeup the userspace poll */
-	input_processed = 1;
+	tc_ev_processed = 1;
 	sysfs_notify(power_kobj, NULL, "touch_event");
+
+	return;
+}
+
+static enum hrtimer_restart tc_ev_stop(struct hrtimer *hrtimer)
+{
+
+	schedule_work(&touch_event_struct);
+
 	return HRTIMER_NORESTART;
 }
 
@@ -434,8 +447,9 @@
 	hibernate_reserved_size_init();
 
 	touch_evt_timer_val = ktime_set(2, 0);
-	hrtimer_init(&in_ev_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	in_ev_timer.function = &input_event_stop;
+	hrtimer_init(&tc_ev_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	tc_ev_timer.function = &tc_ev_stop;
+	tc_ev_processed = 1;
 
 	power_kobj = kobject_create_and_add("power", NULL);
 	if (!power_kobj)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a4b10d8..0ad64a0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4967,15 +4967,16 @@
 			 */
 			pi->amp_move_state =
 				L2CAP_AMP_STATE_WAIT_LOGICAL_CONFIRM;
-		} else if (result == L2CAP_MOVE_CHAN_SUCCESS &&
-			pi->amp_move_state ==
+		} else if (pi->amp_move_state ==
 				L2CAP_AMP_STATE_WAIT_MOVE_RSP_SUCCESS) {
-			/* Logical link is up or moving to BR/EDR,
-			 * proceed with move */
-			if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
+			if (result == L2CAP_MOVE_CHAN_PENDING) {
+				break;
+			} else if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY) {
 				pi->amp_move_state =
 					L2CAP_AMP_STATE_WAIT_LOCAL_BUSY;
 			} else {
+				/* Logical link is up or moving to BR/EDR,
+				 * proceed with move */
 				pi->amp_move_state =
 					L2CAP_AMP_STATE_WAIT_MOVE_CONFIRM_RSP;
 				l2cap_send_move_chan_cfm(conn, pi, pi->scid,
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index cd2d807..c45351e 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -39,6 +39,9 @@
 };
 
 static struct clk *pcm_clk;
+static DEFINE_MUTEX(aux_pcm_mutex);
+static int aux_pcm_count;
+static struct msm_dai_auxpcm_pdata *auxpcm_plat_data;
 
 static u8 num_of_bits_set(u8 sd_line_mask)
 {
@@ -384,24 +387,46 @@
 static void msm_dai_q6_auxpcm_shutdown(struct snd_pcm_substream *substream,
 				struct snd_soc_dai *dai)
 {
-	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	int rc = 0;
 
-	pr_debug("%s: dai->id = %d", __func__, dai->id);
+	mutex_lock(&aux_pcm_mutex);
 
-	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		clk_disable(pcm_clk);
-		rc = afe_close(dai->id); /* can block */
-		if (IS_ERR_VALUE(rc))
-			dev_err(dai->dev, "fail to close AFE port\n");
-		pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
-			*dai_data->status_mask);
-		clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
-
-		rc = afe_close(PCM_TX);
-		if (IS_ERR_VALUE(rc))
-			dev_err(dai->dev, "fail to close AUX PCM TX port\n");
+	if (aux_pcm_count == 0) {
+		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 0. Just"
+				" return\n", __func__, dai->id);
+		mutex_unlock(&aux_pcm_mutex);
+		return;
 	}
+
+	aux_pcm_count--;
+
+	if (aux_pcm_count > 0) {
+		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d\n",
+			__func__, dai->id, aux_pcm_count);
+		mutex_unlock(&aux_pcm_mutex);
+		return;
+	} else if (aux_pcm_count < 0) {
+		dev_err(dai->dev, "%s(): ERROR: dai->id %d"
+			" aux_pcm_count = %d < 0\n",
+			__func__, dai->id, aux_pcm_count);
+		aux_pcm_count = 0;
+		mutex_unlock(&aux_pcm_mutex);
+		return;
+	}
+
+	pr_debug("%s: dai->id = %d aux_pcm_count = %d\n", __func__,
+			dai->id, aux_pcm_count);
+
+	clk_disable(pcm_clk);
+	rc = afe_close(PCM_RX); /* can block */
+	if (IS_ERR_VALUE(rc))
+		dev_err(dai->dev, "fail to close PCM_RX  AFE port\n");
+
+	rc = afe_close(PCM_TX);
+	if (IS_ERR_VALUE(rc))
+		dev_err(dai->dev, "fail to close AUX PCM TX port\n");
+
+	mutex_unlock(&aux_pcm_mutex);
 }
 
 static void msm_dai_q6_shutdown(struct snd_pcm_substream *substream,
@@ -440,49 +465,65 @@
 	struct msm_dai_auxpcm_pdata *auxpcm_pdata =
 			(struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
 
-	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		rc = afe_q6_interface_prepare();
-		if (IS_ERR_VALUE(rc))
-			dev_err(dai->dev, "fail to open AFE APR\n");
+	mutex_lock(&aux_pcm_mutex);
 
-		rc = afe_q6_interface_prepare();
-		if (IS_ERR_VALUE(rc))
-			dev_err(dai->dev, "fail to open AFE APR\n");
-
-		pr_debug("%s:dai->id:%d dai_data->status_mask = %ld\n",
-			__func__, dai->id, *dai_data->status_mask);
-
-		/*
-		 * For AUX PCM Interface the below sequence of clk
-		 * settings and afe_open is a strict requirement.
-		 *
-		 * Also using afe_open instead of afe_port_start_nowait
-		 * to make sure the port is open before deasserting the
-		 * clock line. This is required because pcm register is
-		 * not written before clock deassert. Hence the hw does
-		 * not get updated with new setting if the below clock
-		 * assert/deasset and afe_open sequence is not followed.
-		 */
-
-		clk_reset(pcm_clk, CLK_RESET_ASSERT);
-
-		afe_open(dai->id, &dai_data->port_config,
-			dai_data->rate);
-		set_bit(STATUS_PORT_STARTED,
-			dai_data->status_mask);
-
-		afe_open(PCM_TX, &dai_data->port_config, dai_data->rate);
-
-		rc = clk_set_rate(pcm_clk, auxpcm_pdata->pcm_clk_rate);
-		if (rc < 0) {
-			pr_err("%s: clk_set_rate failed\n", __func__);
-			return rc;
-		}
-
-		clk_enable(pcm_clk);
-		clk_reset(pcm_clk, CLK_RESET_DEASSERT);
-
+	if (aux_pcm_count == 2) {
+		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 2. Just"
+			" return.\n", __func__, dai->id);
+		mutex_unlock(&aux_pcm_mutex);
+		return 0;
+	} else if (aux_pcm_count > 2) {
+		dev_err(dai->dev, "%s(): ERROR: dai->id %d"
+			" aux_pcm_count = %d > 2\n",
+			__func__, dai->id, aux_pcm_count);
+		mutex_unlock(&aux_pcm_mutex);
+		return 0;
 	}
+
+	aux_pcm_count++;
+	if (aux_pcm_count == 2)  {
+		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d after "
+			" increment\n", __func__, dai->id, aux_pcm_count);
+		mutex_unlock(&aux_pcm_mutex);
+		return 0;
+	}
+
+	pr_debug("%s:dai->id:%d  aux_pcm_count = %d. opening afe\n",
+			__func__, dai->id, aux_pcm_count);
+
+	rc = afe_q6_interface_prepare();
+	if (IS_ERR_VALUE(rc))
+		dev_err(dai->dev, "fail to open AFE APR\n");
+
+	/*
+	 * For AUX PCM Interface the below sequence of clk
+	 * settings and afe_open is a strict requirement.
+	 *
+	 * Also using afe_open instead of afe_port_start_nowait
+	 * to make sure the port is open before deasserting the
+	 * clock line. This is required because pcm register is
+	 * not written before clock deassert. Hence the hw does
+	 * not get updated with new setting if the below clock
+	 * assert/deasset and afe_open sequence is not followed.
+	 */
+
+	clk_reset(pcm_clk, CLK_RESET_ASSERT);
+
+	afe_open(PCM_RX, &dai_data->port_config, dai_data->rate);
+
+	afe_open(PCM_TX, &dai_data->port_config, dai_data->rate);
+
+	rc = clk_set_rate(pcm_clk, auxpcm_pdata->pcm_clk_rate);
+	if (rc < 0) {
+		pr_err("%s: clk_set_rate failed\n", __func__);
+		return rc;
+	}
+
+	clk_enable(pcm_clk);
+	clk_reset(pcm_clk, CLK_RESET_DEASSERT);
+
+	mutex_unlock(&aux_pcm_mutex);
+
 	return rc;
 }
 
@@ -504,11 +545,10 @@
 static int msm_dai_q6_auxpcm_trigger(struct snd_pcm_substream *substream,
 		int cmd, struct snd_soc_dai *dai)
 {
-	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	int rc = 0;
 
-	pr_debug("%s:port:%d  cmd:%d dai_data->status_mask = %ld",
-		__func__, dai->id, cmd, *dai_data->status_mask);
+	pr_debug("%s:port:%d  cmd:%d  aux_pcm_count= %d",
+		__func__, dai->id, cmd, aux_pcm_count);
 
 	switch (cmd) {
 
@@ -521,16 +561,7 @@
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-
-			clk_disable(pcm_clk);
-			afe_port_stop_nowait(dai->id);
-			clear_bit(STATUS_PORT_STARTED,
-				dai_data->status_mask);
-
-			afe_port_stop_nowait(PCM_TX);
-		}
-		break;
+		return 0;
 
 	default:
 		rc = -EINVAL;
@@ -605,8 +636,36 @@
 	struct msm_dai_auxpcm_pdata *auxpcm_pdata =
 			(struct msm_dai_auxpcm_pdata *) dai->dev->platform_data;
 
-	dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data),
-		GFP_KERNEL);
+	mutex_lock(&aux_pcm_mutex);
+
+	if (!auxpcm_plat_data)
+		auxpcm_plat_data = auxpcm_pdata;
+	else if (auxpcm_plat_data != auxpcm_pdata) {
+
+		dev_err(dai->dev, "AUX PCM RX and TX devices does not have"
+				" same platform data\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * The clk name for AUX PCM operation is passed as platform
+	 * data to the cpu driver, since cpu drive is unaware of any
+	 * boarc specific configuration.
+	 */
+	if (!pcm_clk) {
+
+		pcm_clk = clk_get(dai->dev, auxpcm_pdata->clk);
+
+		if (IS_ERR(pcm_clk)) {
+			pr_err("%s: could not get pcm_clk\n", __func__);
+			pcm_clk = NULL;
+			return -ENODEV;
+		}
+	}
+
+	mutex_unlock(&aux_pcm_mutex);
+
+	dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data), GFP_KERNEL);
 
 	if (!dai_data) {
 		dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
@@ -615,18 +674,7 @@
 	} else
 		dev_set_drvdata(dai->dev, dai_data);
 
-	/*
-	 * The clk name for AUX PCM operation is passed as platform
-	 * data to the cpu driver, since cpu drive is unaware of any
-	 * boarc specific configuration.
-	 */
-	pcm_clk = clk_get(dai->dev, auxpcm_pdata->clk);
-	if (IS_ERR(pcm_clk)) {
-		pr_err("%s: could not get pcm_clk\n", __func__);
-		return PTR_ERR(pcm_clk);
-		kfree(dai_data);
-	}
-
+	pr_debug("%s : probe done for dai->id %d\n", __func__, dai->id);
 	return rc;
 }
 
@@ -637,22 +685,45 @@
 
 	dai_data = dev_get_drvdata(dai->dev);
 
-	/* If AFE port is still up, close it */
-	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		rc = afe_close(dai->id); /* can block */
-		if (IS_ERR_VALUE(rc))
-			dev_err(dai->dev, "fail to close AFE port\n");
-		clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
+	mutex_lock(&aux_pcm_mutex);
 
-		rc = afe_close(PCM_TX);
-		if (IS_ERR_VALUE(rc))
-			dev_err(dai->dev, "fail to close AUX PCM TX port\n");
+	if (aux_pcm_count == 0) {
+		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count is 0. clean"
+				" up and return\n", __func__, dai->id);
+		goto done;
 	}
 
+	aux_pcm_count--;
 
+	if (aux_pcm_count > 0) {
+		dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d\n",
+			__func__, dai->id, aux_pcm_count);
+		goto done;
+	} else if (aux_pcm_count < 0) {
+		dev_err(dai->dev, "%s(): ERROR: dai->id %d"
+			" aux_pcm_count = %d < 0\n",
+			__func__, dai->id, aux_pcm_count);
+		goto done;
+	}
+
+	dev_dbg(dai->dev, "%s(): dai->id %d aux_pcm_count = %d."
+			"closing afe\n",
+		__func__, dai->id, aux_pcm_count);
+
+	rc = afe_close(PCM_RX); /* can block */
+	if (IS_ERR_VALUE(rc))
+		dev_err(dai->dev, "fail to close AUX PCM RX AFE port\n");
+
+	rc = afe_close(PCM_TX);
+	if (IS_ERR_VALUE(rc))
+		dev_err(dai->dev, "fail to close AUX PCM TX AFE port\n");
+
+done:
 	kfree(dai_data);
 	snd_soc_unregister_dai(dai->dev);
 
+	mutex_unlock(&aux_pcm_mutex);
+
 	return 0;
 }
 static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai)
@@ -1030,6 +1101,9 @@
 		.rate_max = 8000,
 		.rate_min = 8000,
 	},
+	.ops = &msm_dai_q6_auxpcm_ops,
+	.probe = msm_dai_q6_dai_auxpcm_probe,
+	.remove = msm_dai_q6_dai_auxpcm_remove,
 };
 
 static struct snd_soc_dai_driver msm_dai_q6_mi2s_rx_dai = {
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index 1acb57f..575839d6 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -94,6 +94,8 @@
 		pr_debug("ASM_DATA_EVENT_WRITE_DONE\n");
 		pr_debug("Buffer Consumed = 0x%08x\n", *ptrmem);
 		prtd->pcm_irq_pos += prtd->pcm_count;
+		if (prtd->pcm_irq_pos >= prtd->pcm_size)
+			prtd->pcm_irq_pos = 0;
 		if (atomic_read(&prtd->start))
 			snd_pcm_period_elapsed(substream);
 		else
@@ -415,8 +417,6 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct msm_audio *prtd = runtime->private_data;
 
-	if (prtd->pcm_irq_pos >= prtd->pcm_size)
-		prtd->pcm_irq_pos = 0;
 	pr_debug("%s: pcm_irq_pos = %d\n", __func__, prtd->pcm_irq_pos);
 	return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
 }