Merge changes Ib6aa000e,I81885d33 into msm-3.0

* changes:
  usb: msm72k_udc: Delete prime timer after active status bit clear
  usb: msm7k_udc: Add delay upon request dequeue failure
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index e72f4dc..6561c71 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -15,15 +15,20 @@
 		      <0xF9002000 0x1000>;
 	};
 
-	serial@F9684000 {
+	timer {
+		compatible = "qcom,msm-qtimer";
+		interrupts = <18>;
+	};
+
+	serial@F991F000 {
 		compatible = "qcom,msm-lsuart-v14";
-		reg = <0xF9684000 0x1000>;
+		reg = <0xF991F000 0x1000>;
 		interrupts = <109>;
 	};
 
-	usb@F9690000 {
+	usb@F9A55000 {
 		compatible = "qcom,hsusb-otg";
-		reg = <0xF9690000 0x400>;
+		reg = <0xF9A55000 0x400>;
 		interrupts = <134>;
 
 		qcom,hsusb-otg-phy-type = <2>;
@@ -31,10 +36,10 @@
 		qcom,hsusb-otg-otg-control = <1>;
 	};
 
-	qcom,sdcc@F9600000 {
+	qcom,sdcc@F980B000 {
 		cell-index = <1>;
 		compatible = "qcom,msm-sdcc";
-		reg = <0xF9600000 0x1000>;
+		reg = <0xF980B000 0x1000>;
 		interrupts = <123>;
 
 		qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -44,10 +49,10 @@
 		qcom,sdcc-disable_cmd23;
 	};
 
-	qcom,sdcc@F9620000 {
+	qcom,sdcc@F984B000 {
 		cell-index = <3>;
 		compatible = "qcom,msm-sdcc";
-		reg = <0xF9620000 0x1000>;
+		reg = <0xF984B000 0x1000>;
 		interrupts = <127>;
 
 		qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -55,4 +60,14 @@
 		qcom,sdcc-bus-width = <4>;
 		qcom,sdcc-disable_cmd23;
 	};
+
+	qcom,sps@F9980000 {
+		compatible = "qcom,msm_sps";
+		reg = <0xF9984000 0x15000>,
+		      <0xF9999000 0xB000>;
+		interrupts = <94>;
+
+		qcom,bam-dma-res-pipes = <6>;
+	};
+
 };
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 3ab5d76..6f25cf2 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -19,3 +19,4 @@
 obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-sp.o
 obj-$(CONFIG_FIQ_GLUE)		+= fiq_glue.o fiq_glue_setup.o
 obj-$(CONFIG_FIQ_DEBUGGER)	+= fiq_debugger.o
+obj-$(CONFIG_CP_ACCESS)         += cpaccess.o
diff --git a/arch/arm/common/cpaccess.c b/arch/arm/common/cpaccess.c
index d3d0537..e71e318 100644
--- a/arch/arm/common/cpaccess.c
+++ b/arch/arm/common/cpaccess.c
@@ -29,6 +29,7 @@
 #include <linux/smp.h>
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
+#include <asm/mmu_writeable.h>
 
 #ifdef CONFIG_ARCH_MSM_KRAIT
 #include <mach/msm-krait-l2-accessors.h>
@@ -191,16 +192,11 @@
 	(per_cpu(cp_param.cp, cpu) << 8);
 
 	/*
-	 * Grab address of the Dummy function, insert MRC/MCR
-	 * instruction and a return instruction ("bx lr"). Do
-	 * a D cache clean and I cache invalidate after inserting
-	 * new code.
+	 * Grab address of the Dummy function, write the MRC/MCR
+	 * instruction, ensuring cache coherency.
 	 */
 	p_opcode = (unsigned long *)&cpaccess_dummy;
-	*p_opcode++ = opcode;
-	*p_opcode-- = 0xE12FFF1E;
-	__cpuc_coherent_kern_range((unsigned long)p_opcode,
-	 ((unsigned long)p_opcode + (sizeof(long) * 2)));
+	mem_text_write_kernel_word(p_opcode, opcode);
 
 #ifdef CONFIG_SMP
 	/*
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 2b7b749..7fcf9dc 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -35,7 +35,7 @@
 #include <asm/hardware/gic.h>
 #include <asm/system.h>
 
-static DEFINE_SPINLOCK(irq_controller_lock);
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
 
 /* Address of GIC 0 CPU interface */
 void __iomem *gic_cpu_base_addr __read_mostly;
@@ -85,23 +85,22 @@
 {
 	u32 mask = 1 << (d->irq % 32);
 
-	spin_lock(&irq_controller_lock);
+	raw_spin_lock(&irq_controller_lock);
 	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
 	if (gic_arch_extn.irq_mask)
 		gic_arch_extn.irq_mask(d);
-	spin_unlock(&irq_controller_lock);
-
+	raw_spin_unlock(&irq_controller_lock);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
 	u32 mask = 1 << (d->irq % 32);
 
-	spin_lock(&irq_controller_lock);
+	raw_spin_lock(&irq_controller_lock);
 	if (gic_arch_extn.irq_unmask)
 		gic_arch_extn.irq_unmask(d);
 	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
-	spin_unlock(&irq_controller_lock);
+	raw_spin_unlock(&irq_controller_lock);
 }
 
 static void gic_disable_irq(struct irq_data *d)
@@ -149,13 +148,13 @@
 	if (!msm_show_resume_irq_mask)
 		return;
 
-	spin_lock(&irq_controller_lock);
+	raw_spin_lock(&irq_controller_lock);
 	for (i = 0; i * 32 < gic->max_irq; i++) {
 		enabled = readl_relaxed(base + GIC_DIST_ENABLE_CLEAR + i * 4);
 		pending[i] = readl_relaxed(base + GIC_DIST_PENDING_SET + i * 4);
 		pending[i] &= enabled;
 	}
-	spin_unlock(&irq_controller_lock);
+	raw_spin_unlock(&irq_controller_lock);
 
 	for (i = find_first_bit(pending, gic->max_irq);
 	     i < gic->max_irq;
@@ -205,9 +204,9 @@
 static void gic_eoi_irq(struct irq_data *d)
 {
 	if (gic_arch_extn.irq_eoi) {
-		spin_lock(&irq_controller_lock);
+		raw_spin_lock(&irq_controller_lock);
 		gic_arch_extn.irq_eoi(d);
-		spin_unlock(&irq_controller_lock);
+		raw_spin_unlock(&irq_controller_lock);
 	}
 
 	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
@@ -231,7 +230,7 @@
 	if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
 		return -EINVAL;
 
-	spin_lock(&irq_controller_lock);
+	raw_spin_lock(&irq_controller_lock);
 
 	if (gic_arch_extn.irq_set_type)
 		gic_arch_extn.irq_set_type(d, type);
@@ -256,7 +255,7 @@
 	if (enabled)
 		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
 
-	spin_unlock(&irq_controller_lock);
+	raw_spin_unlock(&irq_controller_lock);
 
 	return 0;
 }
@@ -276,22 +275,21 @@
 {
 	void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
 	unsigned int shift = (d->irq % 4) * 8;
-	unsigned int cpu = cpumask_first(mask_val);
+	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
 	u32 val, mask, bit;
 
-	if (cpu >= 8)
+	if (cpu >= 8 || cpu >= nr_cpu_ids)
 		return -EINVAL;
 
 	mask = 0xff << shift;
 	bit = 1 << (cpu + shift);
 
-	spin_lock(&irq_controller_lock);
-	d->node = cpu;
+	raw_spin_lock(&irq_controller_lock);
 	val = readl_relaxed(reg) & ~mask;
 	writel_relaxed(val | bit, reg);
-	spin_unlock(&irq_controller_lock);
+	raw_spin_unlock(&irq_controller_lock);
 
-	return 0;
+	return IRQ_SET_MASK_OK;
 }
 #endif
 
@@ -336,9 +334,9 @@
 
 	chained_irq_enter(chip, desc);
 
-	spin_lock(&irq_controller_lock);
+	raw_spin_lock(&irq_controller_lock);
 	status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK);
-	spin_unlock(&irq_controller_lock);
+	raw_spin_unlock(&irq_controller_lock);
 
 	gic_irq = (status & 0x3ff);
 	if (gic_irq == 1023)
@@ -531,7 +529,7 @@
 	u32 mask, val;
 
 	WARN_ON(!irqs_disabled());
-	spin_lock(&irq_controller_lock);
+	raw_spin_lock(&irq_controller_lock);
 	mask = 1 << (gic_irq(d) % 32);
 	val = readl(gic_dist_base(d) +
 			GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
@@ -539,7 +537,7 @@
 	WARN_ON(val & mask);
 	val = readl(gic_dist_base(d) +
 			GIC_DIST_PENDING_SET + (gic_irq(d) / 32) * 4);
-	spin_unlock(&irq_controller_lock);
+	raw_spin_unlock(&irq_controller_lock);
 	return (bool) (val & mask);
 }
 
@@ -552,7 +550,7 @@
 
 	u32 mask, val;
 	WARN_ON(!irqs_disabled());
-	spin_lock(&irq_controller_lock);
+	raw_spin_lock(&irq_controller_lock);
 	mask = 1 << (gic_irq(d) % 32);
 	val = readl(gic_dist_base(d) +
 			GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
@@ -560,5 +558,5 @@
 	WARN_ON(val & mask);
 	writel(mask, gic_dist_base(d) +
 			GIC_DIST_PENDING_CLEAR + (gic_irq(d) / 32) * 4);
-	spin_unlock(&irq_controller_lock);
+	raw_spin_unlock(&irq_controller_lock);
 }
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index f617aff..4d4c27f 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -44,6 +44,7 @@
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
+CONFIG_ARM_ARCH_TIMER=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
@@ -121,6 +122,9 @@
 CONFIG_ANDROID_TIMED_GPIO=y
 CONFIG_ANDROID_LOW_MEMORY_KILLER=y
 CONFIG_MSM_SSBI=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_BAMDMA=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
diff --git a/arch/arm/configs/msm7627-perf_defconfig b/arch/arm/configs/msm7627-perf_defconfig
index 78eeadd..0f2ffc1 100644
--- a/arch/arm/configs/msm7627-perf_defconfig
+++ b/arch/arm/configs/msm7627-perf_defconfig
@@ -255,6 +255,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
diff --git a/arch/arm/configs/msm7627_defconfig b/arch/arm/configs/msm7627_defconfig
index 4aabe08..d1d0e66 100644
--- a/arch/arm/configs/msm7627_defconfig
+++ b/arch/arm/configs/msm7627_defconfig
@@ -253,6 +253,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
@@ -291,16 +292,13 @@
 CONFIG_LOCKUP_DETECTOR=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_TIMER_STATS=y
-CONFIG_SLUB_DEBUG_ON=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_INFO=y
-CONFIG_LATENCYTOP=y
 CONFIG_DEBUG_LIST=y
+CONFIG_LATENCYTOP=y
 CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index f81cc3d..342aad6 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -104,6 +104,7 @@
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
 CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -119,10 +120,11 @@
 CONFIG_NETFILTER_XT_MATCH_LIMIT=y
 CONFIG_NETFILTER_XT_MATCH_MAC=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
 CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -140,9 +142,11 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=y
 CONFIG_IP_NF_TARGET_NETMAP=y
 CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
 CONFIG_BT=y
 CONFIG_BT_L2CAP=y
 CONFIG_BT_SCO=y
@@ -160,6 +164,8 @@
 CONFIG_CFG80211=y
 # CONFIG_CFG80211_WEXT is not set
 CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -230,8 +236,6 @@
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_IMX072=y
 CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MSM_KGSL=y
 CONFIG_FB=y
 CONFIG_FB_MSM=y
@@ -314,9 +318,6 @@
 CONFIG_DEBUG_SHIRQ=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_TIMER_STATS=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_FTRACE is not set
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 4836af0..c524759 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -102,6 +102,7 @@
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
 CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -117,10 +118,11 @@
 CONFIG_NETFILTER_XT_MATCH_LIMIT=y
 CONFIG_NETFILTER_XT_MATCH_MAC=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
 CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -138,9 +140,11 @@
 CONFIG_IP_NF_TARGET_MASQUERADE=y
 CONFIG_IP_NF_TARGET_NETMAP=y
 CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_ARPTABLES=y
 CONFIG_IP_NF_ARPFILTER=y
 CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
 CONFIG_BT=y
 CONFIG_BT_L2CAP=y
 CONFIG_BT_SCO=y
@@ -158,6 +162,8 @@
 CONFIG_CFG80211=y
 # CONFIG_CFG80211_WEXT is not set
 CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -228,8 +234,6 @@
 CONFIG_MSM_CAMERA_FLASH_SC628A=y
 CONFIG_IMX072=y
 CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MSM_KGSL=y
 CONFIG_FB=y
 CONFIG_FB_MSM=y
@@ -306,20 +310,17 @@
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOCKUP_DETECTOR=y
 CONFIG_DEBUG_SHIRQ=y
+CONFIG_LOCKUP_DETECTOR=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_TIMER_STATS=y
-CONFIG_SLUB_DEBUG_ON=y
 CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_INFO=y
-CONFIG_LATENCYTOP=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_LIST=y
+CONFIG_LATENCYTOP=y
 CONFIG_DEBUG_PAGEALLOC=y
 # CONFIG_FTRACE is not set
 CONFIG_DYNAMIC_DEBUG=y
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 3791d0e..e5fec35 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -99,6 +99,7 @@
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
 CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -115,10 +116,11 @@
 CONFIG_NETFILTER_XT_MATCH_MAC=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
 CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -176,6 +178,8 @@
 # CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -262,8 +266,6 @@
 CONFIG_MT9E013=y
 CONFIG_MSM_GEMINI=y
 CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MSM_KGSL=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
@@ -321,6 +323,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index bd60092..6e3290b 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -98,6 +98,7 @@
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
 CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -114,10 +115,11 @@
 CONFIG_NETFILTER_XT_MATCH_MAC=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
 CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -175,6 +177,8 @@
 # CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -253,8 +257,6 @@
 # CONFIG_MFD_PM8XXX_DEBUG is not set
 # CONFIG_MFD_PM8XXX_PWM is not set
 # CONFIG_MFD_PM8XXX_MISC is not set
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MSM_KGSL=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
@@ -307,6 +309,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
@@ -352,10 +355,7 @@
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
-CONFIG_SLUB_DEBUG_ON=y
 # CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_STACK_USAGE=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index ca64436..01150aa 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -133,6 +133,7 @@
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
 CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -150,10 +151,11 @@
 CONFIG_NETFILTER_XT_MATCH_MAC=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
 CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -216,6 +218,8 @@
 # CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_MISC_DEVICES=y
@@ -320,8 +324,6 @@
 CONFIG_RADIO_TAVARUA=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MSM_KGSL=y
 CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -331,7 +333,6 @@
 CONFIG_FB_MSM_TRIPLE_BUFFER=y
 CONFIG_FB_MSM_MDP40=y
 CONFIG_FB_MSM_OVERLAY=y
-CONFIG_FB_MSM_OVERLAY_WRITEBACK=y
 CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -371,6 +372,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_EMBEDDED_SDIO=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index f78ed74..7b2fede 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -123,6 +123,7 @@
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
 CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -140,10 +141,11 @@
 CONFIG_NETFILTER_XT_MATCH_MAC=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
 CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -206,10 +208,11 @@
 # CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_MISC_DEVICES=y
-CONFIG_KERNEL_DEBUGGER_CORE=y
 CONFIG_UID_STAT=y
 CONFIG_TSIF=m
 CONFIG_TSIF_CHRDEV=m
@@ -308,8 +311,6 @@
 CONFIG_MT9E013=y
 CONFIG_MSM_GEMINI=y
 CONFIG_RADIO_TAVARUA=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MSM_KGSL=y
 CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -319,7 +320,6 @@
 CONFIG_FB_MSM_TRIPLE_BUFFER=y
 CONFIG_FB_MSM_MDP40=y
 CONFIG_FB_MSM_OVERLAY=y
-CONFIG_FB_MSM_OVERLAY_WRITEBACK=y
 CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -357,6 +357,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_EMBEDDED_SDIO=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
@@ -416,16 +417,14 @@
 CONFIG_TIMER_STATS=y
 CONFIG_SLUB_DEBUG_ON=y
 # CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
 CONFIG_PROVE_LOCKING=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_VM=y
 CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index e136a0a..83d012c 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -26,6 +26,7 @@
 CONFIG_EMBEDDED=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
@@ -44,26 +45,28 @@
 CONFIG_MACH_MSM8930_CDP=y
 CONFIG_MACH_MSM8930_MTP=y
 CONFIG_MACH_MSM8930_FLUID=y
+CONFIG_MACH_MSM8627_CDP=y
+CONFIG_MACH_MSM8627_MTP=y
 CONFIG_MACH_APQ8064_SIM=y
 CONFIG_MACH_APQ8064_RUMI3=y
 # CONFIG_MSM_STACKED_MEMORY is not set
 CONFIG_KERNEL_PMEM_EBI_REGION=y
-# CONFIG_MSM_JTAG_V7 is not set
 # CONFIG_MSM_FIQ_SUPPORT is not set
 # CONFIG_MSM_PROC_COMM is not set
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
-CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 CONFIG_MSM_BAM_DMUX=y
 CONFIG_MSM_DSPS=y
 CONFIG_MSM_IPC_ROUTER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 # CONFIG_MSM_HW3D is not set
+CONFIG_MSM_PIL_QDSP6V4=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_MODEM_8960=y
 CONFIG_MSM_LPASS_8960=y
 CONFIG_MSM_WCNSS_SSR_8960=y
-CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_TZ_LOG=y
+CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_RPM_STATS_LOG=y
 CONFIG_MSM_BUS_SCALING=y
 CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
@@ -80,6 +83,7 @@
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_VMALLOC_RESERVE=0x19000000
+CONFIG_CP_ACCESS=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -103,7 +107,6 @@
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -132,6 +135,7 @@
 CONFIG_NF_CONNTRACK_SIP=y
 CONFIG_NF_CONNTRACK_TFTP=y
 CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
@@ -148,10 +152,11 @@
 CONFIG_NETFILTER_XT_MATCH_MAC=y
 CONFIG_NETFILTER_XT_MATCH_MARK=y
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_OWNER=y
 CONFIG_NETFILTER_XT_MATCH_POLICY=y
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
 CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
 CONFIG_NETFILTER_XT_MATCH_STATE=y
 CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
 CONFIG_NETFILTER_XT_MATCH_STRING=y
@@ -198,11 +203,13 @@
 CONFIG_BT_BNEP_PROTO_FILTER=y
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCISMD=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
-CONFIG_MISC_DEVICES=y
 CONFIG_HAPTIC_ISA1200=y
 CONFIG_PMIC8XXX_VIBRATOR=y
 CONFIG_TZCOM=y
@@ -228,8 +235,7 @@
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_WCNSS_CORE=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
+CONFIG_USB_USBNET=y
 CONFIG_SLIP=y
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_MODE_SLIP6=y
@@ -292,8 +298,6 @@
 CONFIG_RADIO_IRIS_TRANSPORT=m
 CONFIG_ION=y
 CONFIG_ION_MSM=y
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
 CONFIG_MSM_KGSL=y
 CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_FB=y
@@ -303,7 +307,6 @@
 CONFIG_FB_MSM_TRIPLE_BUFFER=y
 CONFIG_FB_MSM_MDP40=y
 CONFIG_FB_MSM_OVERLAY=y
-CONFIG_FB_MSM_OVERLAY_WRITEBACK=y
 CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -362,7 +365,6 @@
 CONFIG_MMC_MSM_SDC3_WP_SUPPORT=y
 CONFIG_MMC_MSM_SPS_SUPPORT=y
 CONFIG_LEDS_PM8XXX=y
-# CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_SWITCH=y
@@ -399,7 +401,6 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOCKUP_DETECTOR=y
 # CONFIG_SCHED_DEBUG is not set
@@ -413,6 +414,7 @@
 CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_LIST=y
 CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_SHA256=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index e1b45e1..003f9c1 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -48,6 +48,8 @@
 CONFIG_MSM_MODEM_8960=y
 CONFIG_MSM_LPASS_8960=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
+CONFIG_MSM_BUS_SCALING=y
+CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
 CONFIG_MSM_WATCHDOG=y
 CONFIG_MSM_DLOAD_MODE=y
 # CONFIG_MSM_JTAG_V7 is not set
@@ -92,6 +94,15 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_MISC_DEVICES=y
 # CONFIG_ANDROID_PMEM is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
 CONFIG_NETDEVICES=y
 CONFIG_HOSTAP=y
 # CONFIG_MSM_RMNET is not set
@@ -119,8 +130,6 @@
 CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_MSM is not set
 CONFIG_I2C_QUP=y
-CONFIG_MSM_BUS_SCALING=y
-CONFIG_MSM_BUS_RPM_MULTI_TIER_ENABLED=y
 CONFIG_SPI=y
 CONFIG_SPI_QUP=y
 CONFIG_SPI_SPIDEV=m
@@ -135,7 +144,6 @@
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_SUSPEND=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_EHSET=y
 CONFIG_USB_EHCI_MSM=y
@@ -158,15 +166,6 @@
 CONFIG_USB_G_ANDROID=y
 CONFIG_RMNET_SMD_CTL_CHANNEL="DATA36_CNTL"
 CONFIG_RMNET_SMD_DATA_CHANNEL="DATA36"
-CONFIG_SCSI=y
-CONFIG_SCSI_TGT=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -217,8 +216,6 @@
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_ARC4=y
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEFLATE=y
diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h
index 4200554..8a54b7d 100644
--- a/arch/arm/include/asm/dma.h
+++ b/arch/arm/include/asm/dma.h
@@ -33,18 +33,18 @@
 #define DMA_MODE_CASCADE 0xc0
 #define DMA_AUTOINIT	 0x10
 
-extern spinlock_t  dma_spin_lock;
+extern raw_spinlock_t  dma_spin_lock;
 
 static inline unsigned long claim_dma_lock(void)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&dma_spin_lock, flags);
+	raw_spin_lock_irqsave(&dma_spin_lock, flags);
 	return flags;
 }
 
 static inline void release_dma_lock(unsigned long flags)
 {
-	spin_unlock_irqrestore(&dma_spin_lock, flags);
+	raw_spin_unlock_irqrestore(&dma_spin_lock, flags);
 }
 
 /* Clear the 'DMA Pointer Flip Flop'.
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index b4ffe9d..1496565 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -6,7 +6,7 @@
 typedef struct {
 #ifdef CONFIG_CPU_HAS_ASID
 	unsigned int id;
-	spinlock_t id_lock;
+	raw_spinlock_t id_lock;
 #endif
 	unsigned int kvm_seq;
 } mm_context_t;
@@ -16,7 +16,7 @@
 
 /* init_mm.context.id_lock should be initialized. */
 #define INIT_MM_CONTEXT(name)                                                 \
-	.context.id_lock    = __SPIN_LOCK_UNLOCKED(name.context.id_lock),
+	.context.id_lock    = __RAW_SPIN_LOCK_UNLOCKED(name.context.id_lock),
 #else
 #define ASID(mm)	(0)
 #endif
diff --git a/arch/arm/include/asm/mmu_writeable.h b/arch/arm/include/asm/mmu_writeable.h
index b3ce39b..96d348c 100644
--- a/arch/arm/include/asm/mmu_writeable.h
+++ b/arch/arm/include/asm/mmu_writeable.h
@@ -26,4 +26,6 @@
 static inline void mem_text_writeable_spinunlock(unsigned long *flags) {};
 #endif
 
+void mem_text_write_kernel_word(unsigned long *addr, unsigned long word);
+
 #endif
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index cbb2f45..9693d47 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -485,15 +485,8 @@
  * remap a physical page `pfn' of size `size' with page protection `prot'
  * into virtual address `from'
  */
-#ifndef HAS_ARCH_IO_REMAP_PFN_RANGE
 #define io_remap_pfn_range(vma,from,pfn,size,prot) \
 	remap_pfn_range(vma,from,pfn,size,prot)
-#else
-extern int arch_io_remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot);
-#define io_remap_pfn_range(vma,from,pfn,size,prot) \
-	arch_io_remap_pfn_range(vma,from,pfn,size,prot)
-#endif
-
 
 #define pgtable_cache_init() do { } while (0)
 
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index 5b76911..a920c5f 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/timex.h>
 #include <linux/device.h>
 #include <linux/smp.h>
 #include <linux/cpu.h>
@@ -18,10 +19,13 @@
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/irq.h>
 
 #include <asm/cputype.h>
+#include <asm/sched_clock.h>
 #include <asm/hardware/gic.h>
 
+static struct irqaction arch_irqaction[2];
 static unsigned long arch_timer_rate;
 static int arch_timer_ppi;
 static int arch_timer_ppi2;
@@ -77,13 +81,14 @@
 
 static irqreturn_t arch_timer_handler(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = dev_id;
+	struct clock_event_device *evt;
 	unsigned long ctrl;
 
 	ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
 	if (ctrl & 0x4) {
 		ctrl |= ARCH_TIMER_CTRL_IT_MASK;
 		arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+		evt = per_cpu_ptr(arch_timer_evt, smp_processor_id());
 		evt->event_handler(evt);
 		return IRQ_HANDLED;
 	}
@@ -122,8 +127,8 @@
 	ctrl |= ARCH_TIMER_CTRL_ENABLE;
 	ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
 
-	arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
 	arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+	arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
 
 	return 0;
 }
@@ -131,7 +136,6 @@
 static void __cpuinit arch_timer_setup(void *data)
 {
 	struct clock_event_device *clk = data;
-	int err;
 
 	/* Be safe... */
 	arch_timer_stop();
@@ -147,20 +151,9 @@
 	clockevents_config_and_register(clk, arch_timer_rate,
 					0xf, 0x7fffffff);
 
-	err = gic_request_ppi(clk->irq, arch_timer_handler, clk);
-	if (err) {
-		pr_err("%s: can't register interrupt %d on cpu %d (%d)\n",
-		       clk->name, clk->irq, smp_processor_id(), err);
-		return;
-	}
-
-	if (arch_timer_ppi2 >= 0) {
-		err = gic_request_ppi(arch_timer_ppi2, arch_timer_handler, clk);
-		if (err) {
-			pr_warn("%s: can't register interrupt %d on cpu %d (%d)\n",
-				clk->name, arch_timer_ppi2, smp_processor_id(), err);
-		}
-	}
+	gic_enable_ppi(arch_timer_ppi);
+	if (arch_timer_ppi2 > 0)
+		gic_enable_ppi(arch_timer_ppi2);
 }
 
 /* Is the optional system timer available? */
@@ -218,6 +211,14 @@
 	return arch_counter_get_cntpct();
 }
 
+#ifdef ARCH_HAS_READ_CURRENT_TIMER
+int read_current_timer(unsigned long *timer_val)
+{
+	*timer_val = (unsigned long)arch_counter_get_cntpct();
+	return 0;
+}
+#endif
+
 static struct clocksource clocksource_counter = {
 	.name	= "arch_sys_counter",
 	.rating	= 400,
@@ -240,7 +241,7 @@
 	return (u32)(cntvct & (u32)~0);
 }
 
-DEFINE_SCHED_CLOCK_FUNC(arch_timer_sched_clock)
+unsigned long long notrace sched_clock(void)
 {
 	return cyc_to_sched_clock(&cd, arch_counter_get_cntvct32(), (u32)~0);
 }
@@ -255,9 +256,11 @@
 	struct clock_event_device *clk = data;
 	pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
 		 clk->irq, smp_processor_id());
-	gic_free_ppi(clk->irq, clk);
-	if (arch_timer_ppi2 >= 0)
-		gic_free_ppi(arch_timer_ppi2, clk);
+	if (!smp_processor_id()) {
+		remove_irq(arch_timer_ppi, &arch_irqaction[0]);
+		if (arch_timer_ppi2 > 0)
+			remove_irq(arch_timer_ppi2, &arch_irqaction[1]);
+	}
 	arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
 }
 
@@ -288,6 +291,8 @@
 
 int arch_timer_register(struct resource *res, int res_nr)
 {
+	struct irqaction *irqa;
+	unsigned int cpu = smp_processor_id();
 	int err;
 
 	if (!res_nr || res[0].start < 0 || !(res[0].flags & IORESOURCE_IRQ))
@@ -307,11 +312,41 @@
 
 	clocksource_register_hz(&clocksource_counter, arch_timer_rate);
 
-	init_arch_sched_clock(&cd, arch_timer_update_sched_clock,
-				arch_timer_sched_clock, 32, arch_timer_rate);
+	init_sched_clock(&cd, arch_timer_update_sched_clock, 32,
+			arch_timer_rate);
+
+#ifdef ARCH_HAS_READ_CURRENT_TIMER
+	set_delay_fn(read_current_timer_delay_loop);
+#endif
+
+	irqa = &arch_irqaction[0];
+	irqa->name = "arch_sys_timer";
+	irqa->flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH;
+	irqa->handler = arch_timer_handler;
+	irqa->dev_id = per_cpu_ptr(arch_timer_evt, cpu);
+	irqa->irq = arch_timer_ppi;
+	err = setup_irq(arch_timer_ppi, irqa);
+	if (err) {
+		pr_err("%s: can't register interrupt %d (%d)\n",
+		       irqa->name, irqa->irq, err);
+		return err;
+	}
+
+	if (arch_timer_ppi2 > 0) {
+		irqa = &arch_irqaction[1];
+		irqa->name = "arch_sys_timer";
+		irqa->flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH;
+		irqa->handler = arch_timer_handler;
+		irqa->dev_id = per_cpu_ptr(arch_timer_evt, cpu);
+		irqa->irq = arch_timer_ppi2;
+		err = setup_irq(arch_timer_ppi2, irqa);
+		if (err)
+			pr_warn("%s: can't register interrupt %d (%d)\n",
+				irqa->name, irqa->irq, err);
+	}
 
 	/* Immediately configure the timer on the boot CPU */
-	arch_timer_setup(per_cpu_ptr(arch_timer_evt, smp_processor_id()));
+	arch_timer_setup(per_cpu_ptr(arch_timer_evt, cpu));
 
 	register_cpu_notifier(&arch_timer_cpu_nb);
 
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 2c4a185..7b829d9 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -23,7 +23,7 @@
 
 #include <asm/mach/dma.h>
 
-DEFINE_SPINLOCK(dma_spin_lock);
+DEFINE_RAW_SPINLOCK(dma_spin_lock);
 EXPORT_SYMBOL(dma_spin_lock);
 
 static dma_t *dma_chan[MAX_DMA_CHANNELS];
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 4ef97a0..5bd484f 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -144,54 +144,63 @@
 
 #ifdef CONFIG_HOTPLUG_CPU
 
-static bool migrate_one_irq(struct irq_data *d)
+static bool migrate_one_irq(struct irq_desc *desc)
 {
-	unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask);
+	struct irq_data *d = irq_desc_get_irq_data(desc);
+	const struct cpumask *affinity = d->affinity;
+	struct irq_chip *c;
 	bool ret = false;
 
-	if (cpu >= nr_cpu_ids) {
-		cpu = cpumask_any(cpu_online_mask);
+	/*
+	 * If this is a per-CPU interrupt, or the affinity does not
+	 * include this CPU, then we have nothing to do.
+	 */
+	if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
+		return false;
+
+	if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+		affinity = cpu_online_mask;
 		ret = true;
 	}
 
-	pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu);
-
-	d->chip->irq_set_affinity(d, cpumask_of(cpu), true);
+	c = irq_data_get_irq_chip(d);
+	if (c->irq_set_affinity)
+		c->irq_set_affinity(d, affinity, true);
+	else
+		pr_debug("IRQ%u: unable to set affinity\n", d->irq);
 
 	return ret;
 }
 
 /*
- * The CPU has been marked offline.  Migrate IRQs off this CPU.  If
- * the affinity settings do not allow other CPUs, force them onto any
+ * The current CPU has been marked offline.  Migrate IRQs off this CPU.
+ * If the affinity settings do not allow other CPUs, force them onto any
  * available CPU.
+ *
+ * Note: we must iterate over all IRQs, whether they have an attached
+ * action structure or not, as we need to get chained interrupts too.
  */
 void migrate_irqs(void)
 {
-	unsigned int i, cpu = smp_processor_id();
+	unsigned int i;
 	struct irq_desc *desc;
 	unsigned long flags;
 
 	local_irq_save(flags);
 
 	for_each_irq_desc(i, desc) {
-		struct irq_data *d = &desc->irq_data;
 		bool affinity_broken = false;
 
+		if (!desc)
+			continue;
+
 		raw_spin_lock(&desc->lock);
-		do {
-			if (desc->action == NULL)
-				break;
-
-			if (d->node != cpu)
-				break;
-
-			affinity_broken = migrate_one_irq(d);
-		} while (0);
+		affinity_broken = migrate_one_irq(desc);
 		raw_spin_unlock(&desc->lock);
 
 		if (affinity_broken && printk_ratelimit())
-			pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu);
+			pr_warning("IRQ%u no longer affine to CPU%u\n", i,
+				smp_processor_id());
 	}
 
 	local_irq_restore(flags);
diff --git a/arch/arm/kernel/perf_event_msm_krait_l2.c b/arch/arm/kernel/perf_event_msm_krait_l2.c
index 0512e64..c8b48a8 100644
--- a/arch/arm/kernel/perf_event_msm_krait_l2.c
+++ b/arch/arm/kernel/perf_event_msm_krait_l2.c
@@ -584,10 +584,15 @@
 			return err;
 	}
 
-	hwc->config_base = event->attr.config;
 	hwc->config = 0;
 	hwc->event_base = 0;
 
+	/* Check if we came via perf default syms */
+	if (event->attr.config == PERF_COUNT_HW_L2_CYCLES)
+		hwc->config_base = L2CYCLE_CTR_RAW_CODE;
+	else
+		hwc->config_base = event->attr.config;
+
 	/* Only one CPU can control the cycle counter */
 	if (hwc->config_base == L2CYCLE_CTR_RAW_CODE) {
 		/* Check if its already running */
diff --git a/arch/arm/kernel/perf_event_msm_l2.c b/arch/arm/kernel/perf_event_msm_l2.c
index 3cb251b..33fb5bf 100644
--- a/arch/arm/kernel/perf_event_msm_l2.c
+++ b/arch/arm/kernel/perf_event_msm_l2.c
@@ -10,7 +10,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#ifdef CONFIG_ARCH_MSM8x60
+#ifdef CONFIG_ARCH_MSM8X60
 
 #include <linux/irq.h>
 
@@ -20,6 +20,8 @@
 #define BB_L2CYCLE_CTR_EVENT_IDX 4
 #define BB_L2CYCLE_CTR_RAW_CODE 0xfe
 #define SCORPIONL2_PMNC_E       (1 << 0)	/* Enable all counters */
+#define SCORPION_L2_EVT_PREFIX 3
+#define SCORPION_MAX_L2_REG 4
 
 /*
  * Lock to protect r/m/w sequences to the L2 PMU.
@@ -365,6 +367,26 @@
 				      struct bb_l2_scorp_evt *evtinfo)
 {
 	u32 idx;
+	u8 prefix;
+	u8 reg;
+	u8 code;
+	u8 group;
+
+	prefix = (evt_type & 0xF0000) >> 16;
+	if (prefix == SCORPION_L2_EVT_PREFIX) {
+		reg   = (evt_type & 0x0F000) >> 12;
+		code  = (evt_type & 0x00FF0) >> 4;
+		group =  evt_type & 0x0000F;
+
+		if ((group > 3) || (reg > SCORPION_MAX_L2_REG))
+			return BB_L2_INV_EVTYPE;
+
+		evtinfo->val = 0x80000000 | (code << (group * 8));
+		evtinfo->grp = reg;
+		evtinfo->evt_type_act = group | (reg << 2);
+		return evtinfo->evt_type_act;
+	}
+
 	if (evt_type < BB_L2_EVT_START_IDX || evt_type >= BB_L2_MAX_EVT)
 		return BB_L2_INV_EVTYPE;
 	idx = evt_type - BB_L2_EVT_START_IDX;
@@ -911,10 +933,15 @@
 			return err;
 	}
 
-	hwc->config_base = event->attr.config & 0xff;
 	hwc->config = 0;
 	hwc->event_base = 0;
 
+	/* Check if we came via perf default syms */
+	if (event->attr.config == PERF_COUNT_HW_L2_CYCLES)
+		hwc->config_base = BB_L2CYCLE_CTR_RAW_CODE;
+	else
+		hwc->config_base = event->attr.config;
+
 	/* Only one CPU can control the cycle counter */
 	if (hwc->config_base == BB_L2CYCLE_CTR_RAW_CODE) {
 		/* Check if its already running */
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 9e217ad..8aa7dcb 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -216,7 +216,7 @@
 		pr_err("CPU%u: cpu didn't die\n", cpu);
 		return;
 	}
-	printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+	pr_debug("CPU%u: shutdown\n", cpu);
 
 	if (!platform_cpu_kill(cpu))
 		printk("CPU%u: unable to kill\n", cpu);
@@ -281,7 +281,7 @@
 	struct mm_struct *mm = &init_mm;
 	unsigned int cpu = smp_processor_id();
 
-	printk("CPU%u: Booted secondary processor\n", cpu);
+	pr_debug("CPU%u: Booted secondary processor\n", cpu);
 
 	/*
 	 * All kernel threads share the same mm context; grab a
@@ -535,7 +535,7 @@
 }
 #endif
 
-static DEFINE_SPINLOCK(stop_lock);
+static DEFINE_RAW_SPINLOCK(stop_lock);
 
 /*
  * ipi_cpu_stop - handle IPI from smp_send_stop()
@@ -544,10 +544,10 @@
 {
 	if (system_state == SYSTEM_BOOTING ||
 	    system_state == SYSTEM_RUNNING) {
-		spin_lock(&stop_lock);
+		raw_spin_lock(&stop_lock);
 		printk(KERN_CRIT "CPU%u: stopping\n", cpu);
 		dump_stack();
-		spin_unlock(&stop_lock);
+		raw_spin_unlock(&stop_lock);
 	}
 
 	set_cpu_online(cpu, false);
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 40ee7e5..7669848 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -173,6 +173,57 @@
 	return res;
 }
 
+static int check_condition(struct pt_regs *regs, unsigned int insn)
+{
+	unsigned int base_cond, neg, cond = 0;
+	unsigned int cpsr_z, cpsr_c, cpsr_n, cpsr_v;
+
+	cpsr_n = (regs->ARM_cpsr & PSR_N_BIT) ? 1 : 0;
+	cpsr_z = (regs->ARM_cpsr & PSR_Z_BIT) ? 1 : 0;
+	cpsr_c = (regs->ARM_cpsr & PSR_C_BIT) ? 1 : 0;
+	cpsr_v = (regs->ARM_cpsr & PSR_V_BIT) ? 1 : 0;
+
+	/* Upper 3 bits indicate condition, lower bit incicates negation */
+	base_cond = insn >> 29;
+	neg = insn & BIT(28) ? 1 : 0;
+
+	switch (base_cond) {
+	case 0x0:	/* equal */
+		cond = cpsr_z;
+		break;
+
+	case 0x1:	/* carry set */
+		cond = cpsr_c;
+		break;
+
+	case 0x2:	/* minus / negative */
+		cond = cpsr_n;
+		break;
+
+	case 0x3:	/* overflow */
+		cond = cpsr_v;
+		break;
+
+	case 0x4:	/* unsigned higher */
+		cond = (cpsr_c == 1) && (cpsr_z == 0);
+		break;
+
+	case 0x5:	/* signed greater / equal */
+		cond = (cpsr_n == cpsr_v);
+		break;
+
+	case 0x6:	/* signed greater */
+		cond = (cpsr_z == 0) && (cpsr_n == cpsr_v);
+		break;
+
+	case 0x7:	/* always */
+		cond = 1;
+		break;
+	};
+
+	return cond && !neg;
+}
+
 /*
  * swp_handler logs the id of calling process, dissects the instruction, sanity
  * checks the memory location, calls emulate_swpX for the actual operation and
@@ -191,6 +242,12 @@
 		previous_pid = current->pid;
 	}
 
+	/* Ignore the instruction if it fails its condition code check */
+	if (!check_condition(regs, instr)) {
+		regs->ARM_pc += 4;
+		return 0;
+	}
+
 	address = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
 	data	= regs->uregs[EXTRACT_REG_NUM(instr, RT2_OFFSET)];
 	destreg = EXTRACT_REG_NUM(instr, RT_OFFSET);
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index aaca029..c063c56 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -255,7 +255,7 @@
 	return ret;
 }
 
-static DEFINE_SPINLOCK(die_lock);
+static DEFINE_RAW_SPINLOCK(die_lock);
 
 /*
  * This function is protected against re-entrancy.
@@ -267,7 +267,7 @@
 
 	oops_enter();
 
-	spin_lock_irq(&die_lock);
+	raw_spin_lock_irq(&die_lock);
 	console_verbose();
 	bust_spinlocks(1);
 	ret = __die(str, err, thread, regs);
@@ -277,7 +277,7 @@
 
 	bust_spinlocks(0);
 	add_taint(TAINT_DIE);
-	spin_unlock_irq(&die_lock);
+	raw_spin_unlock_irq(&die_lock);
 	oops_exit();
 
 	if (in_interrupt())
@@ -302,24 +302,24 @@
 }
 
 static LIST_HEAD(undef_hook);
-static DEFINE_SPINLOCK(undef_lock);
+static DEFINE_RAW_SPINLOCK(undef_lock);
 
 void register_undef_hook(struct undef_hook *hook)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&undef_lock, flags);
+	raw_spin_lock_irqsave(&undef_lock, flags);
 	list_add(&hook->node, &undef_hook);
-	spin_unlock_irqrestore(&undef_lock, flags);
+	raw_spin_unlock_irqrestore(&undef_lock, flags);
 }
 
 void unregister_undef_hook(struct undef_hook *hook)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&undef_lock, flags);
+	raw_spin_lock_irqsave(&undef_lock, flags);
 	list_del(&hook->node);
-	spin_unlock_irqrestore(&undef_lock, flags);
+	raw_spin_unlock_irqrestore(&undef_lock, flags);
 }
 
 static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
@@ -328,12 +328,12 @@
 	unsigned long flags;
 	int (*fn)(struct pt_regs *regs, unsigned int instr) = NULL;
 
-	spin_lock_irqsave(&undef_lock, flags);
+	raw_spin_lock_irqsave(&undef_lock, flags);
 	list_for_each_entry(hook, &undef_hook, node)
 		if ((instr & hook->instr_mask) == hook->instr_val &&
 		    (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val)
 			fn = hook->fn;
-	spin_unlock_irqrestore(&undef_lock, flags);
+	raw_spin_unlock_irqrestore(&undef_lock, flags);
 
 	return fn ? fn(regs, instr) : 1;
 }
diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h
index b6fdf23..14db5a0 100644
--- a/arch/arm/mach-footbridge/include/mach/hardware.h
+++ b/arch/arm/mach-footbridge/include/mach/hardware.h
@@ -93,7 +93,7 @@
 #define CPLD_FLASH_WR_ENABLE	1
 
 #ifndef __ASSEMBLY__
-extern spinlock_t nw_gpio_lock;
+extern raw_spinlock_t nw_gpio_lock;
 extern void nw_gpio_modify_op(unsigned int mask, unsigned int set);
 extern void nw_gpio_modify_io(unsigned int mask, unsigned int in);
 extern unsigned int nw_gpio_read(void);
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index 06e514f..5b73190 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -68,7 +68,7 @@
 /*
  * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE
  */
-DEFINE_SPINLOCK(nw_gpio_lock);
+DEFINE_RAW_SPINLOCK(nw_gpio_lock);
 EXPORT_SYMBOL(nw_gpio_lock);
 
 static unsigned int current_gpio_op;
@@ -327,9 +327,9 @@
 	/*
 	 * Set Group1/Group2 outputs
 	 */
-	spin_lock_irqsave(&nw_gpio_lock, flags);
+	raw_spin_lock_irqsave(&nw_gpio_lock, flags);
 	nw_gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN);
-	spin_unlock_irqrestore(&nw_gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
 }
 
 /*
@@ -390,9 +390,9 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&nw_gpio_lock, flags);
+	raw_spin_lock_irqsave(&nw_gpio_lock, flags);
 	nw_cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE);
-	spin_unlock_irqrestore(&nw_gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
 }
 
 static unsigned char rwa_unlock[] __initdata =
@@ -616,9 +616,9 @@
 		cpld_init();
 		rwa010_init();
 
-		spin_lock_irqsave(&nw_gpio_lock, flags);
+		raw_spin_lock_irqsave(&nw_gpio_lock, flags);
 		nw_gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS);
-		spin_unlock_irqrestore(&nw_gpio_lock, flags);
+		raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
 	}
 	return 0;
 }
diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c
index 00269fe..e57102e 100644
--- a/arch/arm/mach-footbridge/netwinder-leds.c
+++ b/arch/arm/mach-footbridge/netwinder-leds.c
@@ -31,13 +31,13 @@
 static char led_state;
 static char hw_led_state;
 
-static DEFINE_SPINLOCK(leds_lock);
+static DEFINE_RAW_SPINLOCK(leds_lock);
 
 static void netwinder_leds_event(led_event_t evt)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&leds_lock, flags);
+	raw_spin_lock_irqsave(&leds_lock, flags);
 
 	switch (evt) {
 	case led_start:
@@ -117,12 +117,12 @@
 		break;
 	}
 
-	spin_unlock_irqrestore(&leds_lock, flags);
+	raw_spin_unlock_irqrestore(&leds_lock, flags);
 
 	if  (led_state & LED_STATE_ENABLED) {
-		spin_lock_irqsave(&nw_gpio_lock, flags);
+		raw_spin_lock_irqsave(&nw_gpio_lock, flags);
 		nw_gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state);
-		spin_unlock_irqrestore(&nw_gpio_lock, flags);
+		raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
 	}
 }
 
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 77315b9..0c20cf6 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -205,7 +205,7 @@
 
 #define CM_CTRL	IO_ADDRESS(INTEGRATOR_HDR_CTRL)
 
-static DEFINE_SPINLOCK(cm_lock);
+static DEFINE_RAW_SPINLOCK(cm_lock);
 
 /**
  * cm_control - update the CM_CTRL register.
@@ -217,10 +217,10 @@
 	unsigned long flags;
 	u32 val;
 
-	spin_lock_irqsave(&cm_lock, flags);
+	raw_spin_lock_irqsave(&cm_lock, flags);
 	val = readl(CM_CTRL) & ~mask;
 	writel(val | set, CM_CTRL);
-	spin_unlock_irqrestore(&cm_lock, flags);
+	raw_spin_unlock_irqrestore(&cm_lock, flags);
 }
 
 EXPORT_SYMBOL(cm_control);
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 6467d99..a9b90a0 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -163,7 +163,7 @@
  *	 7:2	register number
  *  
  */
-static DEFINE_SPINLOCK(v3_lock);
+static DEFINE_RAW_SPINLOCK(v3_lock);
 
 #define PCI_BUS_NONMEM_START	0x00000000
 #define PCI_BUS_NONMEM_SIZE	SZ_256M
@@ -284,7 +284,7 @@
 	unsigned long flags;
 	u32 v;
 
-	spin_lock_irqsave(&v3_lock, flags);
+	raw_spin_lock_irqsave(&v3_lock, flags);
 	addr = v3_open_config_window(bus, devfn, where);
 
 	switch (size) {
@@ -302,7 +302,7 @@
 	}
 
 	v3_close_config_window();
-	spin_unlock_irqrestore(&v3_lock, flags);
+	raw_spin_unlock_irqrestore(&v3_lock, flags);
 
 	*val = v;
 	return PCIBIOS_SUCCESSFUL;
@@ -314,7 +314,7 @@
 	unsigned long addr;
 	unsigned long flags;
 
-	spin_lock_irqsave(&v3_lock, flags);
+	raw_spin_lock_irqsave(&v3_lock, flags);
 	addr = v3_open_config_window(bus, devfn, where);
 
 	switch (size) {
@@ -335,7 +335,7 @@
 	}
 
 	v3_close_config_window();
-	spin_unlock_irqrestore(&v3_lock, flags);
+	raw_spin_unlock_irqrestore(&v3_lock, flags);
 
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -510,7 +510,7 @@
 	hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
 	hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
 
-	spin_lock_irqsave(&v3_lock, flags);
+	raw_spin_lock_irqsave(&v3_lock, flags);
 
 	/*
 	 * Unlock V3 registers, but only if they were previously locked.
@@ -583,7 +583,7 @@
 		printk(KERN_ERR "PCI: unable to grab PCI error "
 		       "interrupt: %d\n", ret);
 
-	spin_unlock_irqrestore(&v3_lock, flags);
+	raw_spin_unlock_irqrestore(&v3_lock, flags);
 }
 
 void __init pci_v3_postinit(void)
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index e9a5893..ab19445 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -54,7 +54,7 @@
  * these transactions are atomic or we will end up
  * with corrupt data on the bus or in a driver.
  */
-static DEFINE_SPINLOCK(ixp4xx_pci_lock);
+static DEFINE_RAW_SPINLOCK(ixp4xx_pci_lock);
 
 /*
  * Read from PCI config space
@@ -62,10 +62,10 @@
 static void crp_read(u32 ad_cbe, u32 *data)
 {
 	unsigned long flags;
-	spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
 	*PCI_CRP_AD_CBE = ad_cbe;
 	*data = *PCI_CRP_RDATA;
-	spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
 }
 
 /*
@@ -74,10 +74,10 @@
 static void crp_write(u32 ad_cbe, u32 data)
 { 
 	unsigned long flags;
-	spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
 	*PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
 	*PCI_CRP_WDATA = data;
-	spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
 }
 
 static inline int check_master_abort(void)
@@ -101,7 +101,7 @@
 	int retval = 0;
 	int i;
 
-	spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
 
 	*PCI_NP_AD = addr;
 
@@ -118,7 +118,7 @@
 	if(check_master_abort())
 		retval = 1;
 
-	spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
 	return retval;
 }
 
@@ -127,7 +127,7 @@
 	unsigned long flags;
 	int retval = 0;
 
-	spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
 
 	*PCI_NP_AD = addr;
 
@@ -140,7 +140,7 @@
 	if(check_master_abort())
 		retval = 1;
 
-	spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
 	return retval;
 }
 
@@ -149,7 +149,7 @@
 	unsigned long flags;
 	int retval = 0;
 
-	spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
 
 	*PCI_NP_AD = addr;
 
@@ -162,7 +162,7 @@
 	if(check_master_abort())
 		retval = 1;
 
-	spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
 	return retval;
 }
 
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index fc27feb..0078ebc 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -146,7 +146,7 @@
 	select MIGRATION
 	select ARCH_MEMORY_PROBE
 	select ARCH_MEMORY_REMOVE
-	select DONT_RESERVE_FROM_MOVABLE_ZONE
+	select FIX_MOVABLE_ZONE
 
 config ARCH_MSM8930
 	bool "MSM8930"
@@ -177,7 +177,7 @@
 	select MIGRATION
 	select ARCH_MEMORY_PROBE
 	select ARCH_MEMORY_REMOVE
-	select DONT_RESERVE_FROM_MOVABLE_ZONE
+	select FIX_MOVABLE_ZONE
 	select MSM_ULTRASOUND
 
 config ARCH_APQ8064
@@ -190,6 +190,9 @@
 	select MSM_SCM if SMP
 	select MSM_GPIOMUX
 	select MSM_REMOTE_SPINLOCK_SFPB
+	select MSM_PIL
+	select MSM_QDSP6_APR
+	select MSM_AUDIO_QDSP6 if SND_SOC
 
 config ARCH_MSMCOPPER
 	bool "MSM Copper"
@@ -252,6 +255,7 @@
 
 config  ARCH_MSM_KRAIT
 	bool
+	select ARM_L1_CACHE_SHIFT_6
 
 config  MSM_SMP
 	bool
@@ -604,6 +608,18 @@
 	help
 	  Support for the Qualcomm MSM8930 FLUID device.
 
+config MACH_MSM8627_CDP
+	depends on ARCH_MSM8930
+	bool "MSM8627 CDP"
+	help
+	  Support for the Qualcomm MSM8627 CDP device.
+
+config MACH_MSM8627_MTP
+	depends on ARCH_MSM8930
+	bool "MSM8627 MTP"
+	help
+	  Support for the Qualcomm MSM8627 MTP device.
+
 config MACH_MSM9615_CDP
 	depends on ARCH_MSM9615
 	bool "MSM9615 CDP"
@@ -1558,6 +1574,14 @@
 
 	  Say yes to support these devices.
 
+config MSM_PIL_QDSP6V4
+	tristate "QDSP6v4 (Hexagon) Boot Support"
+	depends on MSM_PIL
+	help
+	  Support for booting and shutting down QDSP6v4 processors (hexagon).
+	  The QDSP6 is a low power DSP used in audio, modem firmware, and modem
+	  software applications.
+
 config MSM_SCM
 	bool "Secure Channel Manager (SCM) support"
 	default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index bccc05b..05f4ab4 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,4 +1,7 @@
-obj-y += io.o dma.o memory.o timer.o
+obj-y += io.o dma.o memory.o
+ifndef CONFIG_ARM_ARCH_TIMER
+obj-y += timer.o
+endif
 obj-y += clock.o clock-voter.o clock-dummy.o
 obj-y += modem_notifier.o subsystem_map.o
 obj-$(CONFIG_CPU_FREQ_MSM) += cpufreq.o
@@ -68,6 +71,7 @@
 obj-$(CONFIG_ARCH_MSM8X60) += peripheral-reset.o
 obj-$(CONFIG_ARCH_MSM8960) += peripheral-reset-8960.o
 endif
+obj-$(CONFIG_MSM_PIL_QDSP6V4) += pil-q6v4.o
 obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
 obj-$(CONFIG_ARCH_FSM9XXX) += sirc-fsm9xxx.o
 obj-$(CONFIG_MSM_FIQ_SUPPORT) += fiq_glue.o
@@ -99,7 +103,7 @@
 endif
 endif
 endif
-obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o sdio_tty_ciq.o
+obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
 obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
 obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
 obj-$(CONFIG_MSM_SMD_PKT) += smd_pkt.o
@@ -223,16 +227,22 @@
 obj-$(CONFIG_ARCH_MSM8960) += acpuclock-8960.o
 obj-$(CONFIG_ARCH_MSM8960) += memory_topology.o
 obj-$(CONFIG_ARCH_MSM8960) += saw-regulator.o rpm-regulator.o rpm-regulator-8960.o
-obj-$(CONFIG_MACH_MSM8960_SIM) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_CDP) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_MTP) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8960_FLUID) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8930_CDP) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8930_MTP) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
-obj-$(CONFIG_MACH_MSM8930_FLUID) += board-msm8960.o devices-8960.o board-msm8960-regulator.o
+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
+board-8064-all-objs += board-8064.o board-8064-storage.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
+obj-$(CONFIG_MACH_MSM8960_CDP) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8960_MTP) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8960_FLUID) += board-8960-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8930_CDP) += board-8930-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8930_MTP) += board-8930-all.o board-8960-regulator.o
+obj-$(CONFIG_MACH_MSM8930_FLUID) += board-8930-all.o board-8960-regulator.o
 obj-$(CONFIG_ARCH_MSM8960) += bms-batterydata.o
-obj-$(CONFIG_ARCH_APQ8064) += board-apq8064.o devices-8064.o board-apq8064-regulator.o
+obj-$(CONFIG_MACH_APQ8064_SIM) += board-8064-all.o board-8064-regulator.o
+obj-$(CONFIG_MACH_APQ8064_RUMI3) += board-8064-all.o board-8064-regulator.o
 obj-$(CONFIG_ARCH_MSM9615) += board-9615.o devices-9615.o board-9615-regulator.o
 obj-$(CONFIG_ARCH_MSM9615) += clock-local.o clock-9615.o acpuclock-9615.o clock-rpm.o
 obj-$(CONFIG_ARCH_MSM9615) += rpm-regulator.o rpm-regulator-9615.o
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 659c292..143fb86 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -140,7 +140,7 @@
 			.hfpll_base      = MSM_HFPLL_BASE + 0x200,
 			.aux_clk_sel     = MSM_ACC0_BASE  + 0x014,
 			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait0",     1150000 },
+			.vreg[VREG_CORE] = { "krait0",     1300000 },
 			.vreg[VREG_MEM]  = { "krait0_mem", 1150000,
 					     RPM_VREG_VOTER1,
 					     RPM_VREG_ID_PM8921_L24 },
@@ -158,7 +158,7 @@
 			.hfpll_base      = MSM_HFPLL_BASE + 0x300,
 			.aux_clk_sel     = MSM_ACC1_BASE  + 0x014,
 			.l2cpmr_iaddr    = L2CPUCPMR_IADDR,
-			.vreg[VREG_CORE] = { "krait1",     1150000 },
+			.vreg[VREG_CORE] = { "krait1",     1300000 },
 			.vreg[VREG_MEM]  = { "krait0_mem", 1150000,
 					     RPM_VREG_VOTER2,
 					     RPM_VREG_ID_PM8921_L24 },
@@ -287,8 +287,8 @@
 static uint32_t bus_perf_client;
 
 /* TODO: Update vdd_dig and vdd_mem when voltage data is available. */
-#define L2(x) (&l2_freq_tbl_8960[(x)])
-static struct l2_level l2_freq_tbl_8960[] = {
+#define L2(x) (&l2_freq_tbl_8960_kraitv1[(x)])
+static struct l2_level l2_freq_tbl_8960_kraitv1[] = {
 	[0]  = { {STBY_KHZ, QSB,   0, 0, 0x00 }, 1050000, 1050000, 0 },
 	[1]  = { {  384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
 	[2]  = { {  432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
@@ -303,7 +303,7 @@
 	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
 };
 
-static struct acpu_level acpu_freq_tbl_8960[] = {
+static struct acpu_level acpu_freq_tbl_8960_kraitv1[] = {
 	{ 0, {STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   950000 },
 	{ 1, {  384000, PLL_8, 0, 2, 0x00 }, L2(1),   950000 },
 	{ 1, {  432000, HFPLL, 2, 0, 0x20 }, L2(6),   950000 },
@@ -319,6 +319,55 @@
 	{ 0, { 0 } }
 };
 
+#undef L2
+#define L2(x) (&l2_freq_tbl_8960_kraitv2[(x)])
+static struct l2_level l2_freq_tbl_8960_kraitv2[] = {
+	[0]  = { {STBY_KHZ, QSB,   0, 0, 0x00 }, 1050000, 1050000, 0 },
+	[1]  = { {  384000, PLL_8, 0, 2, 0x00 }, 1050000, 1050000, 1 },
+	[2]  = { {  432000, HFPLL, 2, 0, 0x20 }, 1050000, 1050000, 1 },
+	[3]  = { {  486000, HFPLL, 2, 0, 0x24 }, 1050000, 1050000, 1 },
+	[4]  = { {  540000, HFPLL, 2, 0, 0x28 }, 1050000, 1050000, 1 },
+	[5]  = { {  594000, HFPLL, 1, 0, 0x16 }, 1050000, 1050000, 2 },
+	[6]  = { {  648000, HFPLL, 1, 0, 0x18 }, 1050000, 1050000, 2 },
+	[7]  = { {  702000, HFPLL, 1, 0, 0x1A }, 1050000, 1050000, 2 },
+	[8]  = { {  756000, HFPLL, 1, 0, 0x1C }, 1150000, 1150000, 2 },
+	[9]  = { {  810000, HFPLL, 1, 0, 0x1E }, 1150000, 1150000, 3 },
+	[10] = { {  864000, HFPLL, 1, 0, 0x20 }, 1150000, 1150000, 3 },
+	[11] = { {  918000, HFPLL, 1, 0, 0x22 }, 1150000, 1150000, 3 },
+	[12] = { {  972000, HFPLL, 1, 0, 0x24 }, 1150000, 1150000, 4 },
+	[13] = { { 1026000, HFPLL, 1, 0, 0x26 }, 1150000, 1150000, 4 },
+	[14] = { { 1080000, HFPLL, 1, 0, 0x28 }, 1150000, 1150000, 4 },
+	[15] = { { 1134000, HFPLL, 1, 0, 0x2A }, 1150000, 1150000, 4 },
+	[16] = { { 1188000, HFPLL, 1, 0, 0x2C }, 1150000, 1150000, 4 },
+};
+
+static struct acpu_level acpu_freq_tbl_8960_kraitv2[] = {
+	{ 0, { STBY_KHZ, QSB,   0, 0, 0x00 }, L2(0),   950000 },
+	{ 1, {   384000, PLL_8, 0, 2, 0x00 }, L2(1),   950000 },
+	{ 1, {   432000, HFPLL, 2, 0, 0x20 }, L2(6),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0, 0x24 }, L2(6),   962500 },
+	{ 1, {   540000, HFPLL, 2, 0, 0x28 }, L2(6),   962500 },
+	{ 1, {   594000, HFPLL, 1, 0, 0x16 }, L2(6),   987500 },
+	{ 1, {   648000, HFPLL, 1, 0, 0x18 }, L2(6),  1000000 },
+	{ 1, {   702000, HFPLL, 1, 0, 0x1A }, L2(6),  1025000 },
+	{ 1, {   756000, HFPLL, 1, 0, 0x1C }, L2(11), 1050000 },
+	{ 1, {   810000, HFPLL, 1, 0, 0x1E }, L2(11), 1087500 },
+	{ 1, {   864000, HFPLL, 1, 0, 0x20 }, L2(11), 1125000 },
+	{ 1, {   918000, HFPLL, 1, 0, 0x22 }, L2(11), 1137500 },
+	{ 1, {   972000, HFPLL, 1, 0, 0x24 }, L2(16), 1300000 },
+	{ 1, {  1026000, HFPLL, 1, 0, 0x26 }, L2(16), 1300000 },
+	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1300000 },
+	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1300000 },
+	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1300000 },
+	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1300000 },
+	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1300000 },
+	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1300000 },
+	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1300000 },
+	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(16), 1300000 },
+	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(16), 1300000 },
+	{ 0, { 0 } }
+};
+
 /* TODO: Update vdd_dig and vdd_mem when voltage data is available. */
 #undef L2
 #define L2(x) (&l2_freq_tbl_8064[(x)])
@@ -1051,9 +1100,15 @@
 
 		/* TODO: Select tables based on PVS data. */
 		scalable = scalable_8960;
-		acpu_freq_tbl = acpu_freq_tbl_8960;
-		l2_freq_tbl = l2_freq_tbl_8960;
-		l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960);
+		if (cpu_is_krait_v1()) {
+			acpu_freq_tbl = acpu_freq_tbl_8960_kraitv1;
+			l2_freq_tbl = l2_freq_tbl_8960_kraitv1;
+			l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960_kraitv1);
+		} else {
+			acpu_freq_tbl = acpu_freq_tbl_8960_kraitv2;
+			l2_freq_tbl = l2_freq_tbl_8960_kraitv2;
+			l2_freq_tbl_size = ARRAY_SIZE(l2_freq_tbl_8960_kraitv2);
+		}
 	} else if (cpu_is_apq8064()) {
 		scalable = scalable_8064;
 		acpu_freq_tbl = acpu_freq_tbl_8064;
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index ede298d..0041f0d 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -45,6 +45,8 @@
 #define POLLING_MAX_SLEEP	1050	/* 1.05 ms */
 #define POLLING_INACTIVITY	40	/* cycles before switch to intr mode */
 
+#define LOW_WATERMARK		2
+#define HIGH_WATERMARK		4
 
 static int msm_bam_dmux_debug_enable;
 module_param_named(debug_enable, msm_bam_dmux_debug_enable,
@@ -104,6 +106,8 @@
 	spinlock_t lock;
 	struct platform_device *pdev;
 	char name[BAM_DMUX_CH_NAME_MAX_LEN];
+	int num_tx_pkts;
+	int use_wm;
 };
 
 struct tx_pkt_info {
@@ -318,6 +322,7 @@
 	case BAM_MUX_HDR_CMD_OPEN:
 		spin_lock_irqsave(&bam_ch[rx_hdr->ch_id].lock, flags);
 		bam_ch[rx_hdr->ch_id].status |= BAM_CH_REMOTE_OPEN;
+		bam_ch[rx_hdr->ch_id].num_tx_pkts = 0;
 		spin_unlock_irqrestore(&bam_ch[rx_hdr->ch_id].lock, flags);
 		queue_rx();
 		ret = platform_device_add(bam_ch[rx_hdr->ch_id].pdev);
@@ -355,6 +360,7 @@
 	int rc;
 	struct tx_pkt_info *pkt;
 	dma_addr_t dma_address;
+	unsigned long flags;
 
 	pkt = kmalloc(sizeof(struct tx_pkt_info), GFP_ATOMIC);
 	if (pkt == NULL) {
@@ -375,17 +381,17 @@
 	pkt->dma_address = dma_address;
 	pkt->is_cmd = 1;
 	INIT_WORK(&pkt->work, bam_mux_write_done);
-	spin_lock(&bam_tx_pool_spinlock);
+	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	list_add_tail(&pkt->list_node, &bam_tx_pool);
-	spin_unlock(&bam_tx_pool_spinlock);
+	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	rc = sps_transfer_one(bam_tx_pipe, dma_address, len,
 				pkt, SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
 	if (rc) {
 		DBG("%s sps_transfer_one failed rc=%d\n", __func__, rc);
-		spin_lock(&bam_tx_pool_spinlock);
+		spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 		list_del(&pkt->list_node);
 		DBG_INC_TX_SPS_FAILURE_CNT();
-		spin_unlock(&bam_tx_pool_spinlock);
+		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 		kfree(pkt);
 	}
 
@@ -400,13 +406,14 @@
 	struct tx_pkt_info *info;
 	unsigned long event_data;
 	struct list_head *node;
+	unsigned long flags;
 
 	if (in_global_reset)
 		return;
-	spin_lock(&bam_tx_pool_spinlock);
+	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	node = bam_tx_pool.next;
 	list_del(node);
-	spin_unlock(&bam_tx_pool_spinlock);
+	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	info = container_of(work, struct tx_pkt_info, work);
 	if (info->is_cmd) {
 		kfree(info->skb);
@@ -418,6 +425,9 @@
 	hdr = (struct bam_mux_hdr *)skb->data;
 	DBG_INC_WRITE_CNT(skb->data_len);
 	event_data = (unsigned long)(skb);
+	spin_lock_irqsave(&bam_ch[hdr->ch_id].lock, flags);
+	bam_ch[hdr->ch_id].num_tx_pkts--;
+	spin_unlock_irqrestore(&bam_ch[hdr->ch_id].lock, flags);
 	if (bam_ch[hdr->ch_id].notify)
 		bam_ch[hdr->ch_id].notify(
 			bam_ch[hdr->ch_id].priv, BAM_DMUX_WRITE_DONE,
@@ -449,6 +459,13 @@
 		pr_err("%s: port not open: %d\n", __func__, bam_ch[id].status);
 		return -ENODEV;
 	}
+
+	if (bam_ch[id].use_wm &&
+	    (bam_ch[id].num_tx_pkts >= HIGH_WATERMARK)) {
+		spin_unlock_irqrestore(&bam_ch[id].lock, flags);
+		pr_err("%s: watermark exceeded: %d\n", __func__, id);
+		return -EAGAIN;
+	}
 	spin_unlock_irqrestore(&bam_ch[id].lock, flags);
 
 	read_lock(&ul_wakeup_lock);
@@ -508,18 +525,24 @@
 	pkt->dma_address = dma_address;
 	pkt->is_cmd = 0;
 	INIT_WORK(&pkt->work, bam_mux_write_done);
-	spin_lock(&bam_tx_pool_spinlock);
+	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	list_add_tail(&pkt->list_node, &bam_tx_pool);
-	spin_unlock(&bam_tx_pool_spinlock);
+	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	rc = sps_transfer_one(bam_tx_pipe, dma_address, skb->len,
 				pkt, SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT);
 	if (rc) {
 		DBG("%s sps_transfer_one failed rc=%d\n", __func__, rc);
-		spin_lock(&bam_tx_pool_spinlock);
+		spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 		list_del(&pkt->list_node);
 		DBG_INC_TX_SPS_FAILURE_CNT();
-		spin_unlock(&bam_tx_pool_spinlock);
+		spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 		kfree(pkt);
+		if (new_skb)
+			dev_kfree_skb_any(new_skb);
+	} else {
+		spin_lock_irqsave(&bam_ch[id].lock, flags);
+		bam_ch[id].num_tx_pkts++;
+		spin_unlock_irqrestore(&bam_ch[id].lock, flags);
 	}
 	ul_packet_written = 1;
 	read_unlock(&ul_wakeup_lock);
@@ -578,6 +601,8 @@
 	bam_ch[id].notify = notify;
 	bam_ch[id].priv = priv;
 	bam_ch[id].status |= BAM_CH_LOCAL_OPEN;
+	bam_ch[id].num_tx_pkts = 0;
+	bam_ch[id].use_wm = 0;
 	spin_unlock_irqrestore(&bam_ch[id].lock, flags);
 
 	read_lock(&ul_wakeup_lock);
@@ -655,6 +680,47 @@
 	return rc;
 }
 
+int msm_bam_dmux_is_ch_full(uint32_t id)
+{
+	unsigned long flags;
+	int ret;
+
+	if (id >= BAM_DMUX_NUM_CHANNELS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&bam_ch[id].lock, flags);
+	bam_ch[id].use_wm = 1;
+	ret = bam_ch[id].num_tx_pkts >= HIGH_WATERMARK;
+	DBG("%s: ch %d num tx pkts=%d, HWM=%d\n", __func__,
+	     id, bam_ch[id].num_tx_pkts, ret);
+	if (!bam_ch_is_local_open(id)) {
+		ret = -ENODEV;
+		pr_err("%s: port not open: %d\n", __func__, bam_ch[id].status);
+	}
+	spin_unlock_irqrestore(&bam_ch[id].lock, flags);
+
+	return ret;
+}
+
+int msm_bam_dmux_is_ch_low(uint32_t id)
+{
+	int ret;
+
+	if (id >= BAM_DMUX_NUM_CHANNELS)
+		return -EINVAL;
+
+	bam_ch[id].use_wm = 1;
+	ret = bam_ch[id].num_tx_pkts <= LOW_WATERMARK;
+	DBG("%s: ch %d num tx pkts=%d, LWM=%d\n", __func__,
+	     id, bam_ch[id].num_tx_pkts, ret);
+	if (!bam_ch_is_local_open(id)) {
+		ret = -ENODEV;
+		pr_err("%s: port not open: %d\n", __func__, bam_ch[id].status);
+	}
+
+	return ret;
+}
+
 static void rx_timer_work_func(struct work_struct *work)
 {
 	struct sps_iovec iov;
@@ -781,15 +847,7 @@
 					" not disabled\n", __func__);
 				break;
 			}
-			rx_register_event.options = 0;
-			ret = sps_register_event(bam_rx_pipe,
-							&rx_register_event);
-			if (ret) {
-				pr_err("%s: sps_register_event ret = %d\n",
-					__func__, ret);
-				break;
-			}
-			cur_rx_conn.options = SPS_O_AUTO_ENABLE | SPS_O_EOT |
+			cur_rx_conn.options = SPS_O_AUTO_ENABLE |
 				SPS_O_ACK_TRANSFERS | SPS_O_POLL;
 			ret = sps_set_config(bam_rx_pipe, &cur_rx_conn);
 			if (ret) {
@@ -1026,6 +1084,7 @@
 	struct list_head *node;
 	struct tx_pkt_info *info;
 	int temp_remote_status;
+	unsigned long flags;
 
 	if (code != SUBSYS_AFTER_SHUTDOWN)
 		return NOTIFY_DONE;
@@ -1034,6 +1093,7 @@
 	for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
 		temp_remote_status = bam_ch_is_remote_open(i);
 		bam_ch[i].status &= ~BAM_CH_REMOTE_OPEN;
+		bam_ch[i].num_tx_pkts = 0;
 		if (bam_ch_is_local_open(i))
 			bam_ch[i].status |= BAM_CH_IN_RESET;
 		if (temp_remote_status) {
@@ -1043,7 +1103,7 @@
 		}
 	}
 	/*cleanup UL*/
-	spin_lock(&bam_tx_pool_spinlock);
+	spin_lock_irqsave(&bam_tx_pool_spinlock, flags);
 	while (!list_empty(&bam_tx_pool)) {
 		node = bam_tx_pool.next;
 		list_del(node);
@@ -1062,7 +1122,7 @@
 		}
 		kfree(info);
 	}
-	spin_unlock(&bam_tx_pool_spinlock);
+	spin_unlock_irqrestore(&bam_tx_pool_spinlock, flags);
 	smsm_change_state(SMSM_APPS_STATE, SMSM_A2_POWER_CONTROL, 0);
 
 	return NOTIFY_DONE;
diff --git a/arch/arm/mach-msm/board-apq8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
similarity index 97%
rename from arch/arm/mach-msm/board-apq8064-regulator.c
rename to arch/arm/mach-msm/board-8064-regulator.c
index 8448600..4873258 100644
--- a/arch/arm/mach-msm/board-apq8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -13,7 +13,7 @@
 
 #include <linux/regulator/pm8921-regulator.h>
 
-#include "board-apq8064.h"
+#include "board-8064.h"
 
 #define VREG_CONSUMERS(_id) \
 	static struct regulator_consumer_supply vreg_consumers_##_id[]
@@ -93,6 +93,8 @@
 };
 VREG_CONSUMERS(L25) = {
 	REGULATOR_SUPPLY("8921_l25",		NULL),
+	REGULATOR_SUPPLY("VDDD_CDC_D",		"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"tabla-slim"),
 };
 VREG_CONSUMERS(L26) = {
 	REGULATOR_SUPPLY("8921_l26",		NULL),
@@ -118,6 +120,10 @@
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8921_s4",		NULL),
 	REGULATOR_SUPPLY("sdc_vccq",		"msm_sdcc.1"),
+	REGULATOR_SUPPLY("VDDIO_CDC",		"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDD_CP",		"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_TX",		"tabla-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_RX",		"tabla-slim"),
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8921_s5",		NULL),
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
new file mode 100644
index 0000000..8a3b958
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -0,0 +1,257 @@
+/* Copyright (c) 2011, 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/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <asm/mach-types.h>
+#include <asm/mach/mmc.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8064.h"
+
+
+/* APQ8064 has 4 SDCC controllers */
+enum sdcc_controllers {
+	SDCC1,
+	SDCC2,
+	SDCC3,
+	SDCC4,
+	MAX_SDCC_CONTROLLER
+};
+
+/* All SDCC controllers require VDD/VCC voltage */
+static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.name = "sdc_vdd",
+		.high_vol_level = 2950000,
+		.low_vol_level = 2950000,
+		.always_on = 1,
+		.lpm_sup = 1,
+		.lpm_uA = 9000,
+		.hpm_uA = 200000, /* 200mA */
+	},
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.name = "sdc_vdd",
+		.high_vol_level = 2950000,
+		.low_vol_level = 2950000,
+		.hpm_uA = 600000, /* 600mA */
+	}
+};
+
+/* Only slots having eMMC card will require VCCQ voltage */
+static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.name = "sdc_vccq",
+		.always_on = 1,
+		.high_vol_level = 1800000,
+		.low_vol_level = 1800000,
+		.hpm_uA = 200000, /* 200mA */
+	}
+};
+
+/* All SDCC controllers may require voting for VDD PAD voltage */
+static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.name = "sdc_vddp",
+		.high_vol_level = 2950000,
+		.low_vol_level = 1850000,
+		.always_on = 1,
+		.lpm_sup = 1,
+		/* Max. Active current required is 16 mA */
+		.hpm_uA = 16000,
+		/*
+		 * Sleep current required is ~300 uA. But min. vote can be
+		 * in terms of mA (min. 1 mA). So let's vote for 2 mA
+		 * during sleep.
+		 */
+		.lpm_uA = 2000,
+	}
+};
+
+static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.vdd_data = &mmc_vdd_reg_data[SDCC1],
+		.vccq_data = &mmc_vccq_reg_data[SDCC1],
+	},
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.vdd_data = &mmc_vdd_reg_data[SDCC3],
+		.vddp_data = &mmc_vddp_reg_data[SDCC3],
+	}
+};
+
+/* SDC1 pad data */
+static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
+	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
+	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
+	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
+};
+
+static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
+	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
+};
+
+static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
+	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
+	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
+	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
+	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
+};
+
+/* SDC3 pad data */
+static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
+	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
+	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
+	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
+};
+
+static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
+	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
+};
+
+static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
+	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
+	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
+	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_DOWN},
+	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_DOWN}
+};
+
+static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.on = sdc1_pad_pull_on_cfg,
+		.off = sdc1_pad_pull_off_cfg,
+		.size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
+	},
+	[SDCC3] = {
+		.on = sdc3_pad_pull_on_cfg,
+		.off = sdc3_pad_pull_off_cfg,
+		.size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
+	},
+};
+
+static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.on = sdc1_pad_drv_on_cfg,
+		.off = sdc1_pad_drv_off_cfg,
+		.size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
+	},
+	[SDCC3] = {
+		.on = sdc3_pad_drv_on_cfg,
+		.off = sdc3_pad_drv_off_cfg,
+		.size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
+	},
+};
+
+static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.pull = &mmc_pad_pull_data[SDCC1],
+		.drv = &mmc_pad_drv_data[SDCC1]
+	},
+	[SDCC3] = {
+		.pull = &mmc_pad_pull_data[SDCC3],
+		.drv = &mmc_pad_drv_data[SDCC3]
+	},
+};
+
+static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.pad_data = &mmc_pad_data[SDCC1],
+	},
+	[SDCC3] = {
+		.pad_data = &mmc_pad_data[SDCC3],
+	},
+};
+
+#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
+static unsigned int sdc1_sup_clk_rates[] = {
+	400000, 24000000, 48000000, 96000000
+};
+
+static struct mmc_platform_data sdc1_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
+	.mmc_bus_width  = MMC_CAP_8_BIT_DATA,
+#else
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+#endif
+	.sup_clk_table	= sdc1_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
+	.pin_data	= &mmc_slot_pin_data[SDCC1],
+	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
+};
+static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
+#else
+static struct mmc_platform_data *apq8064_sdc1_pdata;
+#endif
+
+#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
+static unsigned int sdc3_sup_clk_rates[] = {
+	400000, 24000000, 48000000, 96000000
+};
+
+static struct mmc_platform_data sdc3_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+	.sup_clk_table	= sdc3_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
+	.pin_data	= &mmc_slot_pin_data[SDCC3],
+	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
+};
+static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
+#else
+static struct mmc_platform_data *apq8064_sdc3_pdata;
+#endif
+
+void __init apq8064_init_mmc(void)
+{
+	if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
+		if (apq8064_sdc1_pdata) {
+			if (machine_is_apq8064_sim())
+				apq8064_sdc1_pdata->disable_bam = true;
+			apq8064_sdc1_pdata->disable_runtime_pm = true;
+			apq8064_sdc1_pdata->disable_cmd23 = true;
+		}
+		if (apq8064_sdc3_pdata) {
+			if (machine_is_apq8064_sim())
+				apq8064_sdc3_pdata->disable_bam = true;
+			apq8064_sdc3_pdata->disable_runtime_pm = true;
+			apq8064_sdc3_pdata->disable_cmd23 = true;
+		}
+	}
+	apq8064_add_sdcc(1, apq8064_sdc1_pdata);
+	apq8064_add_sdcc(3, apq8064_sdc3_pdata);
+}
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-8064.c
similarity index 73%
rename from arch/arm/mach-msm/board-apq8064.c
rename to arch/arm/mach-msm/board-8064.c
index 53c290e..6e2c044 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -16,6 +16,8 @@
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/slimbus/slimbus.h>
+#include <linux/mfd/wcd9310/core.h>
+#include <linux/mfd/wcd9310/pdata.h>
 #include <linux/msm_ssbi.h>
 #include <linux/spi/spi.h>
 #include <linux/dma-mapping.h>
@@ -42,7 +44,7 @@
 #include <mach/dma.h>
 
 #include "msm_watchdog.h"
-#include "board-apq8064.h"
+#include "board-8064.h"
 
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0x600000
 #define MSM_PMEM_ADSP_SIZE         0x3800000
@@ -217,237 +219,46 @@
 	.pclk_src_name		= "dfab_usb_hs_clk",
 };
 
-/* APQ8064 has 4 SDCC controllers */
-enum sdcc_controllers {
-	SDCC1,
-	SDCC2,
-	SDCC3,
-	SDCC4,
-	MAX_SDCC_CONTROLLER
-};
+#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_IRQS)
 
-/* All SDCC controllers require VDD/VCC voltage */
-static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
-	/* SDCC1 : eMMC card connected */
-	[SDCC1] = {
-		.name = "sdc_vdd",
-		.high_vol_level = 2950000,
-		.low_vol_level = 2950000,
-		.always_on = 1,
-		.lpm_sup = 1,
-		.lpm_uA = 9000,
-		.hpm_uA = 200000, /* 200mA */
+/* 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 tabla_pdata apq8064_tabla_platform_data = {
+	.slimbus_slave_device = {
+		.name = "tabla-slave",
+		.e_addr = {0, 0, 0x10, 0, 0x17, 2},
 	},
-	/* SDCC3 : External card slot connected */
-	[SDCC3] = {
-		.name = "sdc_vdd",
-		.high_vol_level = 2950000,
-		.low_vol_level = 2950000,
-		.hpm_uA = 600000, /* 600mA */
+	.irq = MSM_GPIO_TO_INT(62),
+	.irq_base = TABLA_INTERRUPT_BASE,
+	.num_irqs = NR_TABLA_IRQS,
+	.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+	.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,
 	}
 };
 
-/* Only slots having eMMC card will require VCCQ voltage */
-static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
-	/* SDCC1 : eMMC card connected */
-	[SDCC1] = {
-		.name = "sdc_vccq",
-		.always_on = 1,
-		.high_vol_level = 1800000,
-		.low_vol_level = 1800000,
-		.hpm_uA = 200000, /* 200mA */
-	}
-};
-
-/* All SDCC controllers may require voting for VDD PAD voltage */
-static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
-	/* SDCC3 : External card slot connected */
-	[SDCC3] = {
-		.name = "sdc_vddp",
-		.high_vol_level = 2950000,
-		.low_vol_level = 1850000,
-		.always_on = 1,
-		.lpm_sup = 1,
-		/* Max. Active current required is 16 mA */
-		.hpm_uA = 16000,
-		/*
-		 * Sleep current required is ~300 uA. But min. vote can be
-		 * in terms of mA (min. 1 mA). So let's vote for 2 mA
-		 * during sleep.
-		 */
-		.lpm_uA = 2000,
-	}
-};
-
-static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
-	/* SDCC1 : eMMC card connected */
-	[SDCC1] = {
-		.vdd_data = &mmc_vdd_reg_data[SDCC1],
-		.vccq_data = &mmc_vccq_reg_data[SDCC1],
-	},
-	/* SDCC3 : External card slot connected */
-	[SDCC3] = {
-		.vdd_data = &mmc_vdd_reg_data[SDCC3],
-		.vddp_data = &mmc_vddp_reg_data[SDCC3],
-	}
-};
-
-/* SDC1 pad data */
-static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
-	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
-	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
-	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
-};
-
-static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
-	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
-};
-
-static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
-	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
-	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
-	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
-};
-
-static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
-	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
-	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
-	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
-};
-
-/* SDC3 pad data */
-static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
-	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
-	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
-	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
-};
-
-static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
-	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
-};
-
-static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
-	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
-	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
-	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
-};
-
-static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
-	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
-	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_DOWN},
-	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_DOWN}
-};
-
-static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.on = sdc1_pad_pull_on_cfg,
-		.off = sdc1_pad_pull_off_cfg,
-		.size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
-	},
-	[SDCC3] = {
-		.on = sdc3_pad_pull_on_cfg,
-		.off = sdc3_pad_pull_off_cfg,
-		.size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
+static struct slim_device apq8064_slim_tabla = {
+	.name = "tabla-slim",
+	.e_addr = {0, 1, 0x10, 0, 0x17, 2},
+	.dev = {
+		.platform_data = &apq8064_tabla_platform_data,
 	},
 };
 
-static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.on = sdc1_pad_drv_on_cfg,
-		.off = sdc1_pad_drv_off_cfg,
-		.size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
-	},
-	[SDCC3] = {
-		.on = sdc3_pad_drv_on_cfg,
-		.off = sdc3_pad_drv_off_cfg,
-		.size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
-	},
-};
-
-static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.pull = &mmc_pad_pull_data[SDCC1],
-		.drv = &mmc_pad_drv_data[SDCC1]
-	},
-	[SDCC3] = {
-		.pull = &mmc_pad_pull_data[SDCC3],
-		.drv = &mmc_pad_drv_data[SDCC3]
-	},
-};
-
-static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.pad_data = &mmc_pad_data[SDCC1],
-	},
-	[SDCC3] = {
-		.pad_data = &mmc_pad_data[SDCC3],
-	},
-};
-
-#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
-static unsigned int sdc1_sup_clk_rates[] = {
-	400000, 24000000, 48000000, 96000000
-};
-
-static struct mmc_platform_data sdc1_data = {
-	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
-#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
-	.mmc_bus_width  = MMC_CAP_8_BIT_DATA,
-#else
-	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
-#endif
-	.sup_clk_table	= sdc1_sup_clk_rates,
-	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
-	.pin_data	= &mmc_slot_pin_data[SDCC1],
-	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
-};
-static struct mmc_platform_data *apq8064_sdc1_pdata = &sdc1_data;
-#else
-static struct mmc_platform_data *apq8064_sdc1_pdata;
-#endif
-
-#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
-static unsigned int sdc3_sup_clk_rates[] = {
-	400000, 24000000, 48000000, 96000000
-};
-
-static struct mmc_platform_data sdc3_data = {
-	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
-	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
-	.sup_clk_table	= sdc3_sup_clk_rates,
-	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
-	.pin_data	= &mmc_slot_pin_data[SDCC3],
-	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
-};
-static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
-#else
-static struct mmc_platform_data *apq8064_sdc3_pdata;
-#endif
-
-static void __init apq8064_init_mmc(void)
-{
-	if ((machine_is_apq8064_rumi3()) || machine_is_apq8064_sim()) {
-		if (apq8064_sdc1_pdata) {
-			if (machine_is_apq8064_sim())
-				apq8064_sdc1_pdata->disable_bam = true;
-			apq8064_sdc1_pdata->disable_runtime_pm = true;
-			apq8064_sdc1_pdata->disable_cmd23 = true;
-		}
-		if (apq8064_sdc3_pdata) {
-			if (machine_is_apq8064_sim())
-				apq8064_sdc3_pdata->disable_bam = true;
-			apq8064_sdc3_pdata->disable_runtime_pm = true;
-			apq8064_sdc3_pdata->disable_cmd23 = true;
-		}
-	}
-	apq8064_add_sdcc(1, apq8064_sdc1_pdata);
-	apq8064_add_sdcc(3, apq8064_sdc3_pdata);
-}
-
 #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
 		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
 		defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
@@ -652,6 +463,31 @@
 		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
 	&qcedev_device,
 #endif
+
+#ifdef CONFIG_HW_RANDOM_MSM
+	&apq8064_device_rng,
+#endif
+	&msm_pcm,
+	&msm_pcm_routing,
+	&msm_cpudai0,
+	&msm_cpudai1,
+	&msm_cpudai_hdmi_rx,
+	&msm_cpudai_bt_rx,
+	&msm_cpudai_bt_tx,
+	&msm_cpudai_fm_rx,
+	&msm_cpudai_fm_tx,
+	&msm_cpu_fe,
+	&msm_stub_codec,
+	&msm_voice,
+	&msm_voip,
+	&msm_lpa_pcm,
+	&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,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
@@ -662,6 +498,10 @@
 static struct platform_device *rumi3_devices[] __initdata = {
 	&apq8064_device_uart_gsbi1,
 	&msm_device_sps_apq8064,
+	&msm_cpudai_bt_rx,
+	&msm_cpudai_bt_tx,
+	&msm_cpudai_fm_rx,
+	&msm_cpudai_fm_tx,
 };
 
 static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
@@ -806,7 +646,11 @@
 };
 
 static struct slim_boardinfo apq8064_slim_devices[] = {
-	/* Add slimbus slaves as needed */
+	{
+	.bus_num = 1,
+	.slim_slave = &apq8064_slim_tabla,
+	},
+	/* add more slimbus slaves as needed */
 };
 
 static struct msm_i2c_platform_data apq8064_i2c_qup_gsbi4_pdata = {
@@ -814,6 +658,52 @@
 	.src_clk_rate = 24000000,
 };
 
+
+static struct gpiomux_setting audio_auxpcm[] = {
+	/* Suspended state */
+	{
+		.func = GPIOMUX_FUNC_GPIO,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+	/* Active state */
+	{
+		.func = GPIOMUX_FUNC_1,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+};
+static struct msm_gpiomux_config apq8064_audio_auxpcm_configs[] __initdata = {
+	{
+		.gpio = 43,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 44,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 45,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 46,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+};
+
 static void __init apq8064_i2c_init(void)
 {
 	apq8064_device_qup_i2c_gsbi4.dev.platform_data =
@@ -834,6 +724,8 @@
 
 	msm_gpiomux_install(apq8064_gsbi_configs,
 			ARRAY_SIZE(apq8064_gsbi_configs));
+	msm_gpiomux_install(apq8064_audio_auxpcm_configs,
+			ARRAY_SIZE(apq8064_audio_auxpcm_configs));
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/board-apq8064.h b/arch/arm/mach-msm/board-8064.h
similarity index 98%
rename from arch/arm/mach-msm/board-apq8064.h
rename to arch/arm/mach-msm/board-8064.h
index 0928a58..d9da00a 100644
--- a/arch/arm/mach-msm/board-apq8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -41,4 +41,5 @@
 int __init apq8064_add_sdcc(unsigned int controller,
 		struct mmc_platform_data *plat);
 
+void apq8064_init_mmc(void);
 #endif
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
new file mode 100644
index 0000000..9161fbf
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -0,0 +1,470 @@
+/* Copyright (c) 2011, 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/i2c.h>
+#include <linux/i2c/sx150x.h>
+#include <asm/mach-types.h>
+#include <mach/board.h>
+#include <mach/msm_bus_board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8930.h"
+
+#if (defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)) && \
+	defined(CONFIG_I2C)
+
+static struct i2c_board_info cam_expander_i2c_info[] = {
+	{
+		I2C_BOARD_INFO("sx1508q", 0x22),
+		.platform_data = &msm8930_sx150x_data[SX150X_CAM]
+	},
+};
+
+static struct msm_cam_expander_info cam_expander_info[] = {
+	{
+		cam_expander_i2c_info,
+		MSM_8930_GSBI4_QUP_I2C_BUS_ID,
+	},
+};
+#endif
+
+static struct gpiomux_setting cam_settings[] = {
+	{
+		.func = GPIOMUX_FUNC_GPIO, /*suspend*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_DOWN,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_1, /*active 1*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_GPIO, /*active 2*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_1, /*active 3*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_5, /*active 4*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_6, /*active 5*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_2, /*active 6*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_3, /*active 7*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_GPIO, /*i2c suspend*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_KEEPER,
+	},
+
+};
+
+
+static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
+	{
+		.gpio = 2,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 3,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 4,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 5,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 76,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 107,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
+	{
+		.gpio = 18,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 19,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 20,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 21,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+};
+
+#ifdef CONFIG_MSM_CAMERA
+
+static uint16_t msm_cam_gpio_2d_tbl[] = {
+	5, /*CAMIF_MCLK*/
+	20, /*CAMIF_I2C_DATA*/
+	21, /*CAMIF_I2C_CLK*/
+};
+
+static struct msm_camera_gpio_conf gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
+	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
+};
+
+#define VFE_CAMIF_TIMER1_GPIO 2
+#define VFE_CAMIF_TIMER2_GPIO 3
+#define VFE_CAMIF_TIMER3_GPIO_INT 4
+static struct msm_camera_sensor_strobe_flash_data strobe_flash_xenon = {
+	.flash_trigger = VFE_CAMIF_TIMER2_GPIO,
+	.flash_charge = VFE_CAMIF_TIMER1_GPIO,
+	.flash_charge_done = VFE_CAMIF_TIMER3_GPIO_INT,
+	.flash_recharge_duration = 50000,
+	.irq = MSM_GPIO_TO_INT(VFE_CAMIF_TIMER3_GPIO_INT),
+};
+
+#ifdef CONFIG_MSM_CAMERA_FLASH
+static struct msm_camera_sensor_flash_src msm_flash_src = {
+	.flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
+	._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
+	._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
+#if defined(CONFIG_I2C) && (defined(CONFIG_GPIO_SX150X) || \
+			defined(CONFIG_GPIO_SX150X_MODULE))
+	._fsrc.ext_driver_src.expander_info = cam_expander_info,
+#endif
+};
+#endif
+
+static struct msm_bus_vectors cam_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_preview_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 27648000,
+		.ib  = 110592000,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_video_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 140451840,
+		.ib  = 561807360,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 206807040,
+		.ib  = 488816640,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_snapshot_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 274423680,
+		.ib  = 1097694720,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 540000000,
+		.ib  = 1350000000,
+	},
+};
+
+static struct msm_bus_vectors cam_zsl_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 302071680,
+		.ib  = 1208286720,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 540000000,
+		.ib  = 1350000000,
+	},
+};
+
+static struct msm_bus_paths cam_bus_client_config[] = {
+	{
+		ARRAY_SIZE(cam_init_vectors),
+		cam_init_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_preview_vectors),
+		cam_preview_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_video_vectors),
+		cam_video_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_snapshot_vectors),
+		cam_snapshot_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_zsl_vectors),
+		cam_zsl_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata cam_bus_client_pdata = {
+		cam_bus_client_config,
+		ARRAY_SIZE(cam_bus_client_config),
+		.name = "msm_camera",
+};
+
+static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
+	{
+		.ioclk.mclk_clk_rate = 24000000,
+		.ioclk.vfe_clk_rate  = 228570000,
+		.csid_core = 0,
+		.cam_bus_scale_table = &cam_bus_client_pdata,
+	},
+	{
+		.ioclk.mclk_clk_rate = 24000000,
+		.ioclk.vfe_clk_rate  = 228570000,
+		.csid_core = 1,
+		.cam_bus_scale_table = &cam_bus_client_pdata,
+	},
+};
+
+#ifdef CONFIG_IMX074_ACT
+static struct i2c_board_info imx074_actuator_i2c_info = {
+	I2C_BOARD_INFO("imx074_act", 0x11),
+};
+
+static struct msm_actuator_info imx074_actuator_info = {
+	.board_info     = &imx074_actuator_i2c_info,
+	.bus_id         = MSM_8930_GSBI4_QUP_I2C_BUS_ID,
+	.vcm_pwd        = 0,
+	.vcm_enable     = 1,
+};
+#endif
+
+#ifdef CONFIG_IMX074
+static struct msm_camera_sensor_flash_data flash_imx074 = {
+	.flash_type	= MSM_CAMERA_FLASH_LED,
+#ifdef CONFIG_MSM_CAMERA_FLASH
+	.flash_src	= &msm_flash_src
+#endif
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
+	.mount_angle	= 90,
+	.sensor_reset	= 107,
+	.sensor_pwd	= 85,
+	.vcm_pwd	= 0,
+	.vcm_enable	= 1,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
+	.sensor_name	= "imx074",
+	.pdata	= &msm_camera_csi_device_data[0],
+	.flash_data	= &flash_imx074,
+	.strobe_flash_data = &strobe_flash_xenon,
+	.sensor_platform_info = &sensor_board_info_imx074,
+	.gpio_conf = &gpio_conf,
+	.csi_if	= 1,
+	.camera_type = BACK_CAMERA_2D,
+#ifdef CONFIG_IMX074_ACT
+	.actuator_info = &imx074_actuator_info
+#endif
+};
+
+static struct platform_device msm8960_camera_sensor_imx074 = {
+	.name	= "msm_camera_imx074",
+	.dev	= {
+		.platform_data = &msm_camera_sensor_imx074_data,
+	},
+};
+#endif
+#ifdef CONFIG_OV2720
+static struct msm_camera_sensor_flash_data flash_ov2720 = {
+	.flash_type	= MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
+	.mount_angle	= 0,
+	.sensor_reset	= 76,
+	.sensor_pwd	= 85,
+	.vcm_pwd	= 0,
+	.vcm_enable	= 1,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
+	.sensor_name	= "ov2720",
+	.pdata	= &msm_camera_csi_device_data[1],
+	.flash_data	= &flash_ov2720,
+	.sensor_platform_info = &sensor_board_info_ov2720,
+	.gpio_conf = &gpio_conf,
+	.csi_if	= 1,
+	.camera_type = FRONT_CAMERA_2D,
+};
+
+static struct platform_device msm8960_camera_sensor_ov2720 = {
+	.name	= "msm_camera_ov2720",
+	.dev	= {
+		.platform_data = &msm_camera_sensor_ov2720_data,
+	},
+};
+#endif
+
+void __init msm8930_init_cam(void)
+{
+	int i;
+	struct platform_device *cam_dev[] = {
+		&msm8960_camera_sensor_imx074,
+		&msm8960_camera_sensor_ov2720,
+	};
+
+	msm_gpiomux_install(msm8960_cam_common_configs,
+			ARRAY_SIZE(msm8960_cam_common_configs));
+
+	for (i = 0; i < ARRAY_SIZE(cam_dev); i++) {
+		struct msm_camera_sensor_info *s_info;
+		s_info = cam_dev[i]->dev.platform_data;
+		msm_get_cam_resources(s_info);
+		platform_device_register(cam_dev[i]);
+	}
+
+	platform_device_register(&msm8960_device_csiphy0);
+	platform_device_register(&msm8960_device_csiphy1);
+	platform_device_register(&msm8960_device_csid0);
+	platform_device_register(&msm8960_device_csid1);
+	platform_device_register(&msm8960_device_ispif);
+	platform_device_register(&msm8960_device_vfe);
+	platform_device_register(&msm8960_device_vpe);
+}
+#endif
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
new file mode 100644
index 0000000..ca21fac
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -0,0 +1,793 @@
+/* Copyright (c) 2011, 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/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <asm/mach-types.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
+#include "devices.h"
+#include "board-8930.h"
+
+#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
+#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 3) /* 4 bpp x 3 pages */
+#else
+#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 2) /* 4 bpp x 2 pages */
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+#define MSM_FB_EXT_BUF_SIZE	(1920 * 1088 * 2 * 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 */
+#else
+#define MSM_FB_EXT_BUF_SIZE	0
+#endif
+
+#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+/* width x height x 3 bpp x 2 frame buffer */
+#define MSM_FB_WRITEBACK_SIZE (1376 * 768 * 3 * 2)
+#define MSM_FB_WRITEBACK_OFFSET  \
+		(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE)
+#else
+#define MSM_FB_WRITEBACK_SIZE   0
+#define MSM_FB_WRITEBACK_OFFSET 0
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+/* 4 bpp x 2 page HDMI case */
+#define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
+#else
+/* Note: must be multiple of 4096 */
+#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
+				MSM_FB_WRITEBACK_SIZE, 4096)
+#endif
+
+#define MDP_VSYNC_GPIO 0
+
+#define PANEL_NAME_MAX_LEN	30
+#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME	"mipi_cmd_novatek_qhd"
+#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME	"mipi_video_novatek_qhd"
+#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME	"mipi_video_toshiba_wsvga"
+#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME	"mipi_video_chimei_wxga"
+#define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME	"mipi_video_simulator_vga"
+#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME	"mipi_cmd_renesas_fwvga"
+#define HDMI_PANEL_NAME	"hdmi_msm"
+#define TVOUT_PANEL_NAME	"tvout_msm"
+
+static int writeback_offset(void)
+{
+	return MSM_FB_WRITEBACK_OFFSET;
+}
+
+static struct resource msm_fb_resources[] = {
+	{
+		.flags = IORESOURCE_DMA,
+	}
+};
+
+static int msm_fb_detect_panel(const char *name)
+{
+	if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
+			strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+#ifndef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+	if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+			strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+	if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+			strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+	if (!strncmp(name, MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
+			strnlen(MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+	if (!strncmp(name, MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+			strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+#endif
+
+	if (!strncmp(name, HDMI_PANEL_NAME,
+			strnlen(HDMI_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+	if (!strncmp(name, TVOUT_PANEL_NAME,
+			strnlen(TVOUT_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+	pr_warning("%s: not supported '%s'", __func__, name);
+	return -ENODEV;
+}
+
+static struct msm_fb_platform_data msm_fb_pdata = {
+	.detect_client = msm_fb_detect_panel,
+};
+
+static struct platform_device msm_fb_device = {
+	.name   = "msm_fb",
+	.id     = 0,
+	.num_resources     = ARRAY_SIZE(msm_fb_resources),
+	.resource          = msm_fb_resources,
+	.dev.platform_data = &msm_fb_pdata,
+};
+
+static bool dsi_power_on;
+
+static int mipi_dsi_cdp_panel_power(int on)
+{
+	static struct regulator *reg_l8, *reg_l23, *reg_l2;
+	static int gpio43;
+	int rc;
+
+	pr_info("%s: state : %d\n", __func__, on);
+
+	if (!dsi_power_on) {
+
+		reg_l8 = regulator_get(&msm_mipi_dsi1_device.dev,
+				"dsi_vdc");
+		if (IS_ERR(reg_l8)) {
+			pr_err("could not get 8921_l8, rc = %ld\n",
+				PTR_ERR(reg_l8));
+			return -ENODEV;
+		}
+		reg_l23 = regulator_get(&msm_mipi_dsi1_device.dev,
+				"dsi_vddio");
+		if (IS_ERR(reg_l23)) {
+			pr_err("could not get 8921_l23, rc = %ld\n",
+				PTR_ERR(reg_l23));
+			return -ENODEV;
+		}
+		reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
+				"dsi_vdda");
+		if (IS_ERR(reg_l2)) {
+			pr_err("could not get 8921_l2, rc = %ld\n",
+				PTR_ERR(reg_l2));
+			return -ENODEV;
+		}
+		rc = regulator_set_voltage(reg_l8, 2800000, 3000000);
+		if (rc) {
+			pr_err("set_voltage l8 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_voltage(reg_l23, 1800000, 1800000);
+		if (rc) {
+			pr_err("set_voltage l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
+		if (rc) {
+			pr_err("set_voltage l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		gpio43 = PM8921_GPIO_PM_TO_SYS(43);
+		rc = gpio_request(gpio43, "disp_rst_n");
+		if (rc) {
+			pr_err("request gpio 43 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		dsi_power_on = true;
+	}
+	if (on) {
+		rc = regulator_set_optimum_mode(reg_l8, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l23, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l2, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_enable(reg_l8);
+		if (rc) {
+			pr_err("enable l8 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_enable(reg_l23);
+		if (rc) {
+			pr_err("enable l8 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_enable(reg_l2);
+		if (rc) {
+			pr_err("enable l2 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		gpio_set_value_cansleep(gpio43, 1);
+	} else {
+		rc = regulator_disable(reg_l2);
+		if (rc) {
+			pr_err("disable reg_l2 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_disable(reg_l8);
+		if (rc) {
+			pr_err("disable reg_l8 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_disable(reg_l23);
+		if (rc) {
+			pr_err("disable reg_l23 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_set_optimum_mode(reg_l8, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l23, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l2, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		gpio_set_value_cansleep(gpio43, 0);
+	}
+	return 0;
+}
+
+static int mipi_dsi_panel_power(int on)
+{
+	pr_info("%s: on=%d\n", __func__, on);
+
+	return mipi_dsi_cdp_panel_power(on);
+}
+
+static struct mipi_dsi_platform_data mipi_dsi_pdata = {
+	.vsync_gpio = MDP_VSYNC_GPIO,
+	.dsi_power_save = mipi_dsi_panel_power,
+};
+
+#ifdef CONFIG_MSM_BUS_SCALING
+
+static struct msm_bus_vectors mdp_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+static struct msm_bus_vectors hdmi_as_primary_vectors[] = {
+	/* If HDMI is used as primary */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 2000000000,
+		.ib = 2000000000,
+	},
+};
+static struct msm_bus_paths mdp_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(mdp_init_vectors),
+		mdp_init_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+};
+#else
+static struct msm_bus_vectors mdp_ui_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 216000000 * 2,
+		.ib = 270000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_vga_vectors[] = {
+	/* VGA and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 216000000 * 2,
+		.ib = 270000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_720p_vectors[] = {
+	/* 720p and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 230400000 * 2,
+		.ib = 288000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_1080p_vectors[] = {
+	/* 1080p and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 334080000 * 2,
+		.ib = 417600000 * 2,
+	},
+};
+
+static struct msm_bus_paths mdp_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(mdp_init_vectors),
+		mdp_init_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_ui_vectors),
+		mdp_ui_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_ui_vectors),
+		mdp_ui_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_vga_vectors),
+		mdp_vga_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_720p_vectors),
+		mdp_720p_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_1080p_vectors),
+		mdp_1080p_vectors,
+	},
+};
+#endif
+
+static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
+	mdp_bus_scale_usecases,
+	ARRAY_SIZE(mdp_bus_scale_usecases),
+	.name = "mdp",
+};
+
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+static int mdp_core_clk_rate_table[] = {
+	200000000,
+	200000000,
+	200000000,
+	200000000,
+};
+#else
+static int mdp_core_clk_rate_table[] = {
+	85330000,
+	85330000,
+	160000000,
+	200000000,
+};
+#endif
+
+static struct msm_panel_common_pdata mdp_pdata = {
+	.gpio = MDP_VSYNC_GPIO,
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+	.mdp_core_clk_rate = 200000000,
+#else
+	.mdp_core_clk_rate = 85330000,
+#endif
+	.mdp_core_clk_table = mdp_core_clk_rate_table,
+	.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+#ifdef CONFIG_MSM_BUS_SCALING
+	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
+#endif
+	.mdp_rev = MDP_REV_42,
+	.writeback_offset = writeback_offset,
+};
+
+#define LPM_CHANNEL0 0
+static int toshiba_gpio[] = {LPM_CHANNEL0};
+
+static struct mipi_dsi_panel_platform_data toshiba_pdata = {
+	.gpio = toshiba_gpio,
+};
+
+static struct platform_device mipi_dsi_toshiba_panel_device = {
+	.name = "mipi_toshiba",
+	.id = 0,
+	.dev = {
+		.platform_data = &toshiba_pdata,
+	}
+};
+
+#define FPGA_3D_GPIO_CONFIG_ADDR	0xB5
+
+static struct mipi_dsi_phy_ctrl dsi_novatek_cmd_mode_phy_db = {
+
+/* DSI_BIT_CLK at 500MHz, 2 lane, RGB888 */
+	{0x0F, 0x0a, 0x04, 0x00, 0x20},	/* regulator */
+	/* timing   */
+	{0xab, 0x8a, 0x18, 0x00, 0x92, 0x97, 0x1b, 0x8c,
+	0x0c, 0x03, 0x04, 0xa0},
+	{0x5f, 0x00, 0x00, 0x10},	/* phy ctrl */
+	{0xff, 0x00, 0x06, 0x00},	/* strength */
+	/* pll control */
+	{0x40, 0xf9, 0x30, 0xda, 0x00, 0x40, 0x03, 0x62,
+	0x40, 0x07, 0x03,
+	0x00, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01},
+};
+
+static struct mipi_dsi_panel_platform_data novatek_pdata = {
+	.fpga_3d_config_addr  = FPGA_3D_GPIO_CONFIG_ADDR,
+	.fpga_ctrl_mode = FPGA_SPI_INTF,
+	.phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
+};
+
+static struct platform_device mipi_dsi_novatek_panel_device = {
+	.name = "mipi_novatek",
+	.id = 0,
+	.dev = {
+		.platform_data = &novatek_pdata,
+	}
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct resource hdmi_msm_resources[] = {
+	{
+		.name  = "hdmi_msm_qfprom_addr",
+		.start = 0x00700000,
+		.end   = 0x007060FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.name  = "hdmi_msm_hdmi_addr",
+		.start = 0x04A00000,
+		.end   = 0x04A00FFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.name  = "hdmi_msm_irq",
+		.start = HDMI_IRQ,
+		.end   = HDMI_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static int hdmi_enable_5v(int on);
+static int hdmi_core_power(int on, int show);
+static int hdmi_cec_power(int on);
+
+static struct msm_hdmi_platform_data hdmi_msm_data = {
+	.irq = HDMI_IRQ,
+	.enable_5v = hdmi_enable_5v,
+	.core_power = hdmi_core_power,
+	.cec_power = hdmi_cec_power,
+};
+
+static struct platform_device hdmi_msm_device = {
+	.name = "hdmi_msm",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(hdmi_msm_resources),
+	.resource = hdmi_msm_resources,
+	.dev.platform_data = &hdmi_msm_data,
+};
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
+
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+static struct platform_device wfd_panel_device = {
+	.name = "wfd_panel",
+	.id = 0,
+	.dev.platform_data = NULL,
+};
+
+static struct platform_device wfd_device = {
+	.name          = "msm_wfd",
+	.id            = -1,
+};
+#endif
+
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors dtv_bus_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+#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,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 566092800 * 2,
+		.ib = 707616000 * 2,
+	},
+};
+#endif
+
+static struct msm_bus_paths dtv_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(dtv_bus_init_vectors),
+		dtv_bus_init_vectors,
+	},
+	{
+		ARRAY_SIZE(dtv_bus_def_vectors),
+		dtv_bus_def_vectors,
+	},
+};
+static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
+	dtv_bus_scale_usecases,
+	ARRAY_SIZE(dtv_bus_scale_usecases),
+	.name = "dtv",
+};
+
+static struct lcdc_platform_data dtv_pdata = {
+	.bus_scale_table = &dtv_bus_scale_pdata,
+};
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static int hdmi_enable_5v(int on)
+{
+	/* TBD: PM8921 regulator instead of 8901 */
+	static struct regulator *reg_8921_hdmi_mvs;	/* HDMI_5V */
+	static int prev_on;
+	int rc;
+
+	if (on == prev_on)
+		return 0;
+
+	if (!reg_8921_hdmi_mvs)
+		reg_8921_hdmi_mvs = regulator_get(&hdmi_msm_device.dev,
+			"hdmi_mvs");
+
+	if (on) {
+		rc = regulator_enable(reg_8921_hdmi_mvs);
+		if (rc) {
+			pr_err("'%s' regulator enable failed, rc=%d\n",
+				"8921_hdmi_mvs", rc);
+			return rc;
+		}
+		pr_debug("%s(on): success\n", __func__);
+	} else {
+		rc = regulator_disable(reg_8921_hdmi_mvs);
+		if (rc)
+			pr_warning("'%s' regulator disable failed, rc=%d\n",
+				"8921_hdmi_mvs", rc);
+		pr_debug("%s(off): success\n", __func__);
+	}
+
+	prev_on = on;
+
+	return 0;
+}
+
+static int hdmi_core_power(int on, int show)
+{
+	static struct regulator *reg_8921_l23, *reg_8921_s4;
+	static int prev_on;
+	int rc;
+
+	if (on == prev_on)
+		return 0;
+
+	/* TBD: PM8921 regulator instead of 8901 */
+	if (!reg_8921_l23) {
+		reg_8921_l23 = regulator_get(&hdmi_msm_device.dev, "hdmi_avdd");
+		if (IS_ERR(reg_8921_l23)) {
+			pr_err("could not get reg_8921_l23, rc = %ld\n",
+				PTR_ERR(reg_8921_l23));
+			return -ENODEV;
+		}
+		rc = regulator_set_voltage(reg_8921_l23, 1800000, 1800000);
+		if (rc) {
+			pr_err("set_voltage failed for 8921_l23, rc=%d\n", rc);
+			return -EINVAL;
+		}
+	}
+	if (!reg_8921_s4) {
+		reg_8921_s4 = regulator_get(&hdmi_msm_device.dev, "hdmi_vcc");
+		if (IS_ERR(reg_8921_s4)) {
+			pr_err("could not get reg_8921_s4, rc = %ld\n",
+				PTR_ERR(reg_8921_s4));
+			return -ENODEV;
+		}
+		rc = regulator_set_voltage(reg_8921_s4, 1800000, 1800000);
+		if (rc) {
+			pr_err("set_voltage failed for 8921_s4, rc=%d\n", rc);
+			return -EINVAL;
+		}
+	}
+
+	if (on) {
+		rc = regulator_set_optimum_mode(reg_8921_l23, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_enable(reg_8921_l23);
+		if (rc) {
+			pr_err("'%s' regulator enable failed, rc=%d\n",
+				"hdmi_avdd", rc);
+			return rc;
+		}
+		rc = regulator_enable(reg_8921_s4);
+		if (rc) {
+			pr_err("'%s' regulator enable failed, rc=%d\n",
+				"hdmi_vcc", rc);
+			return rc;
+		}
+		rc = gpio_request(100, "HDMI_DDC_CLK");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_DDC_CLK", 100, rc);
+			goto error1;
+		}
+		rc = gpio_request(101, "HDMI_DDC_DATA");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_DDC_DATA", 101, rc);
+			goto error2;
+		}
+		rc = gpio_request(102, "HDMI_HPD");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_HPD", 102, rc);
+			goto error3;
+		}
+		pr_debug("%s(on): success\n", __func__);
+	} else {
+		gpio_free(100);
+		gpio_free(101);
+		gpio_free(102);
+
+		rc = regulator_disable(reg_8921_l23);
+		if (rc) {
+			pr_err("disable reg_8921_l23 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_disable(reg_8921_s4);
+		if (rc) {
+			pr_err("disable reg_8921_s4 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_set_optimum_mode(reg_8921_l23, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		pr_debug("%s(off): success\n", __func__);
+	}
+
+	prev_on = on;
+
+	return 0;
+
+error3:
+	gpio_free(101);
+error2:
+	gpio_free(100);
+error1:
+	regulator_disable(reg_8921_l23);
+	regulator_disable(reg_8921_s4);
+	return rc;
+}
+
+static int hdmi_cec_power(int on)
+{
+	static int prev_on;
+	int rc;
+
+	if (on == prev_on)
+		return 0;
+
+	if (on) {
+		rc = gpio_request(99, "HDMI_CEC_VAR");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_CEC_VAR", 99, rc);
+			goto error;
+		}
+		pr_debug("%s(on): success\n", __func__);
+	} else {
+		gpio_free(99);
+		pr_debug("%s(off): success\n", __func__);
+	}
+
+	prev_on = on;
+
+	return 0;
+error:
+	return rc;
+}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
+
+void __init msm8930_init_fb(void)
+{
+	platform_device_register(&msm_fb_device);
+
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+	platform_device_register(&wfd_panel_device);
+	platform_device_register(&wfd_device);
+#endif
+
+	platform_device_register(&mipi_dsi_novatek_panel_device);
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+	if (!cpu_is_msm8627())
+		platform_device_register(&hdmi_msm_device);
+#endif
+
+	platform_device_register(&mipi_dsi_toshiba_panel_device);
+
+	msm_fb_register_device("mdp", &mdp_pdata);
+	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
+#ifdef CONFIG_MSM_BUS_SCALING
+	msm_fb_register_device("dtv", &dtv_pdata);
+#endif
+}
+
+void __init msm8930_allocate_fb_region(void)
+{
+	void *addr;
+	unsigned long size;
+
+	size = MSM_FB_SIZE;
+	addr = alloc_bootmem_align(size, 0x1000);
+	msm_fb_resources[0].start = __pa(addr);
+	msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
+	pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
+			size, addr, __pa(addr));
+}
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
new file mode 100644
index 0000000..e872d64
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -0,0 +1,662 @@
+/* Copyright (c) 2011, 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 <asm/mach-types.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
+#include "devices.h"
+#include "board-8930.h"
+
+/* The SPI configurations apply to GSBI 1*/
+static struct gpiomux_setting spi_active = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_12MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting spi_active_config2 = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config2 = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting gsbi3_suspended_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting gsbi3_active_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi5 = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi10 = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi12 = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting cdc_mclk = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting audio_auxpcm[] = {
+	/* Suspended state */
+	{
+		.func = GPIOMUX_FUNC_GPIO,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+	/* Active state */
+	{
+		.func = GPIOMUX_FUNC_1,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+};
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct gpiomux_setting gpio_eth_config = {
+	.pull = GPIOMUX_PULL_NONE,
+	.drv = GPIOMUX_DRV_8MA,
+	.func = GPIOMUX_FUNC_GPIO,
+};
+#endif
+
+static struct gpiomux_setting slimbus = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv  = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting wcnss_5wire_active_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv  = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_resout_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_resout_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_sleep_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_sleep_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_int_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_int_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct gpiomux_setting hsic_act_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_12MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting hsic_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+	.dir = GPIOMUX_OUT_LOW,
+};
+
+static struct gpiomux_setting hsic_hub_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+#endif
+
+static struct gpiomux_setting hap_lvl_shft_suspended_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hap_lvl_shft_active_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting ap2mdm_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdm2ap_status_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdm2ap_errfatal_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_16MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdp_vsync_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdp_vsync_active_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct gpiomux_setting hdmi_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hdmi_active_1_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting hdmi_active_2_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+#endif
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct msm_gpiomux_config msm8960_ethernet_configs[] = {
+	{
+		.gpio = 90,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
+		}
+	},
+	{
+		.gpio = 89,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
+		}
+	},
+};
+#endif
+
+static struct msm_gpiomux_config msm8960_gsbi_configs[] __initdata = {
+	{
+		.gpio      = 6,		/* GSBI1 QUP SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 7,		/* GSBI1 QUP SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 8,		/* GSBI1 QUP SPI_CS_N */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 9,		/* GSBI1 QUP SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 14,		/* GSBI1 SPI_CS_1 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config2,
+			[GPIOMUX_ACTIVE] = &spi_active_config2,
+		},
+	},
+	{
+		.gpio      = 16,	/* GSBI3 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+		},
+	},
+	{
+		.gpio      = 17,	/* GSBI3 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+		},
+	},
+	{
+		.gpio      = 22,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 23,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 24,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 25,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 44,	/* GSBI12 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi12,
+		},
+	},
+	{
+		.gpio      = 45,	/* GSBI12 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi12,
+		},
+	},
+	{
+		.gpio      = 73,	/* GSBI10 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi10,
+		},
+	},
+	{
+		.gpio      = 74,	/* GSBI10 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi10,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
+	{
+		.gpio	= 60,		/* slimbus data */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &slimbus,
+		},
+	},
+	{
+		.gpio	= 61,		/* slimbus clk */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &slimbus,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_audio_codec_configs[] __initdata = {
+	{
+		.gpio = 59,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &cdc_mclk,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
+	{
+		.gpio = 63,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 64,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 65,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 66,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+};
+
+static struct msm_gpiomux_config wcnss_5wire_interface[] = {
+	{
+		.gpio = 84,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 85,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 86,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 87,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 88,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_cyts_configs[] __initdata = {
+	{	/* TS INTERRUPT */
+		.gpio = 11,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cyts_int_act_cfg,
+			[GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
+		},
+	},
+	{	/* TS SLEEP */
+		.gpio = 50,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cyts_sleep_act_cfg,
+			[GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
+		},
+	},
+	{	/* TS RESOUT */
+		.gpio = 52,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cyts_resout_act_cfg,
+			[GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
+		},
+	},
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct msm_gpiomux_config msm8960_hsic_configs[] = {
+	{
+		.gpio = 150,               /*HSIC_STROBE */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+	{
+		.gpio = 151,               /* HSIC_DATA */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+	{
+		.gpio = 91,               /* HSIC_HUB_RESET */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+};
+#endif
+
+static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
+	{
+		.gpio = 47,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
+			[GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
+		},
+	},
+};
+
+static struct msm_gpiomux_config mdm_configs[] __initdata = {
+	/* AP2MDM_STATUS */
+	{
+		.gpio = 94,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* MDM2AP_STATUS */
+	{
+		.gpio = 69,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+		}
+	},
+	/* MDM2AP_ERRFATAL */
+	{
+		.gpio = 70,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+		}
+	},
+	/* AP2MDM_ERRFATAL */
+	{
+		.gpio = 95,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* AP2MDM_KPDPWR_N */
+	{
+		.gpio = 81,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+		}
+	},
+	/* AP2MDM_PMIC_RESET_N */
+	{
+		.gpio = 80,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+		}
+	}
+};
+
+static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
+	{
+		.gpio = 0,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &mdp_vsync_active_cfg,
+			[GPIOMUX_SUSPENDED] = &mdp_vsync_suspend_cfg,
+		},
+	}
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct msm_gpiomux_config msm8960_hdmi_configs[] __initdata = {
+	{
+		.gpio = 99,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 100,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 101,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 102,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_2_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+};
+#endif
+
+int __init msm8930_init_gpiomux(void)
+{
+	int rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	if (rc) {
+		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
+		return rc;
+	}
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+	msm_gpiomux_install(msm8960_ethernet_configs,
+			ARRAY_SIZE(msm8960_ethernet_configs));
+#endif
+
+	msm_gpiomux_install(msm8960_gsbi_configs,
+			ARRAY_SIZE(msm8960_gsbi_configs));
+
+	msm_gpiomux_install(msm8960_cyts_configs,
+			ARRAY_SIZE(msm8960_cyts_configs));
+
+	msm_gpiomux_install(msm8960_slimbus_config,
+			ARRAY_SIZE(msm8960_slimbus_config));
+
+	msm_gpiomux_install(msm8960_audio_codec_configs,
+			ARRAY_SIZE(msm8960_audio_codec_configs));
+
+	msm_gpiomux_install(msm8960_audio_auxpcm_configs,
+			ARRAY_SIZE(msm8960_audio_auxpcm_configs));
+
+	msm_gpiomux_install(wcnss_5wire_interface,
+			ARRAY_SIZE(wcnss_5wire_interface));
+
+	if (machine_is_msm8930_mtp() || machine_is_msm8930_fluid() ||
+		machine_is_msm8930_cdp())
+		msm_gpiomux_install(hap_lvl_shft_config,
+			ARRAY_SIZE(hap_lvl_shft_config));
+
+	if (PLATFORM_IS_CHARM25())
+		msm_gpiomux_install(mdm_configs,
+			ARRAY_SIZE(mdm_configs));
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+	if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1) &&
+			!machine_is_msm8930_mtp() &&
+			!machine_is_msm8930_fluid())
+		msm_gpiomux_install(msm8960_hsic_configs,
+			ARRAY_SIZE(msm8960_hsic_configs));
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+	msm_gpiomux_install(msm8960_hdmi_configs,
+			ARRAY_SIZE(msm8960_hdmi_configs));
+#endif
+
+	msm_gpiomux_install(msm8960_mdp_vsync_configs,
+			ARRAY_SIZE(msm8960_mdp_vsync_configs));
+	return 0;
+}
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
new file mode 100644
index 0000000..cfb2347
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -0,0 +1,499 @@
+/* Copyright (c) 2011, 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/interrupt.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
+#include <linux/msm_ssbi.h>
+#include <asm/mach-types.h>
+#include <mach/msm_bus_board.h>
+#include <mach/restart.h>
+#include "devices.h"
+#include "board-8930.h"
+
+struct pm8xxx_gpio_init {
+	unsigned			gpio;
+	struct pm_gpio			config;
+};
+
+struct pm8xxx_mpp_init {
+	unsigned			mpp;
+	struct pm8xxx_mpp_config_data	config;
+};
+
+#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+			_func, _inv, _disable) \
+{ \
+	.gpio	= PM8921_GPIO_PM_TO_SYS(_gpio), \
+	.config	= { \
+		.direction	= _dir, \
+		.output_buffer	= _buf, \
+		.output_value	= _val, \
+		.pull		= _pull, \
+		.vin_sel	= _vin, \
+		.out_strength	= _out_strength, \
+		.function	= _func, \
+		.inv_int_pol	= _inv, \
+		.disable_pin	= _disable, \
+	} \
+}
+
+#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8921_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
+
+#define PM8XXX_GPIO_DISABLE(_gpio) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+			 0, 0, 0, 1)
+
+#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+			_pull, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_NO, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8XXX_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_HIGH, \
+			_func, 0, 0)
+
+#define PM8XXX_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, _vin, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+/* Initial PM8921 GPIO configurations */
+static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
+	PM8XXX_GPIO_DISABLE(6),				 /* Disable unused */
+	PM8XXX_GPIO_DISABLE(7),				 /* Disable NFC */
+	PM8XXX_GPIO_INPUT(16,	    PM_GPIO_PULL_UP_30), /* SD_CARD_WP */
+    /* External regulator shared by display and touchscreen on LiQUID */
+	PM8XXX_GPIO_OUTPUT(17,	    0),			 /* DISP 3.3 V Boost */
+	PM8XXX_GPIO_OUTPUT_VIN(21, 1, PM_GPIO_VIN_VPH),	 /* Backlight Enable */
+	PM8XXX_GPIO_DISABLE(22),			 /* Disable NFC */
+	PM8XXX_GPIO_OUTPUT_FUNC(24, 0, PM_GPIO_FUNC_2),	 /* Bl: Off, PWM mode */
+	PM8XXX_GPIO_INPUT(26,	    PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
+	PM8XXX_GPIO_OUTPUT(43,	    PM_GPIO_PULL_UP_30), /* DISP_RESET_N */
+	PM8XXX_GPIO_OUTPUT(42, 0),                      /* USB 5V reg enable */
+};
+
+/* Initial PM8921 MPP configurations */
+static struct pm8xxx_mpp_init pm8921_mpps[] __initdata = {
+	/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
+	PM8XXX_MPP_INIT(7, D_INPUT, PM8921_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
+	PM8XXX_MPP_INIT(PM8XXX_AMUX_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
+								DOUT_CTRL_LOW),
+};
+
+void __init msm8930_pm8921_gpio_mpp_init(void)
+{
+	int i, rc;
+
+	for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
+		rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
+					&pm8921_gpios[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pm8921_mpps); i++) {
+		rc = pm8xxx_mpp_config(pm8921_mpps[i].mpp,
+					&pm8921_mpps[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+}
+
+static struct pm8xxx_adc_amux pm8xxx_adc_channels_data[] = {
+	{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
+	{"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
+	{"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"pa_therm1", ADC_MPP_1_AMUX8, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+	{"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
+	{"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+};
+
+static struct pm8xxx_adc_properties pm8xxx_adc_data = {
+	.adc_vdd_reference	= 1800, /* milli-voltage for this adc */
+	.bitresolution		= 15,
+	.bipolar                = 0,
+};
+
+static struct pm8xxx_adc_platform_data pm8xxx_adc_pdata = {
+	.adc_channel            = pm8xxx_adc_channels_data,
+	.adc_num_board_channel  = ARRAY_SIZE(pm8xxx_adc_channels_data),
+	.adc_prop               = &pm8xxx_adc_data,
+	.adc_mpp_base		= PM8921_MPP_PM_TO_SYS(1),
+};
+
+
+static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata __devinitdata = {
+	.irq_base		= PM8921_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(104),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
+};
+
+static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata __devinitdata = {
+	.gpio_base	= PM8921_GPIO_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata __devinitdata = {
+	.mpp_base	= PM8921_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_rtc_platform_data pm8xxx_rtc_pdata __devinitdata = {
+	.rtc_write_enable       = false,
+	.rtc_alarm_powerup	= false,
+};
+
+static struct pm8xxx_pwrkey_platform_data pm8xxx_pwrkey_pdata = {
+	.pull_up		= 1,
+	.kpd_trigger_delay_us	= 970,
+	.wakeup			= 1,
+};
+
+/* Rotate lock key is not available so use F1 */
+#define KEY_ROTATE_LOCK KEY_F1
+
+static const unsigned int keymap_liquid[] = {
+	KEY(0, 0, KEY_VOLUMEUP),
+	KEY(0, 1, KEY_VOLUMEDOWN),
+	KEY(1, 3, KEY_ROTATE_LOCK),
+	KEY(1, 4, KEY_HOME),
+};
+
+static const unsigned int keymap[] = {
+	KEY(0, 0, KEY_VOLUMEUP),
+	KEY(0, 1, KEY_VOLUMEDOWN),
+	KEY(0, 2, KEY_CAMERA_SNAPSHOT),
+	KEY(0, 3, KEY_CAMERA_FOCUS),
+};
+
+static struct matrix_keymap_data keymap_data = {
+	.keymap_size    = ARRAY_SIZE(keymap),
+	.keymap         = keymap,
+};
+
+static struct pm8xxx_keypad_platform_data keypad_data = {
+	.input_name             = "keypad_8960",
+	.input_phys_device      = "keypad_8960/input0",
+	.num_rows               = 1,
+	.num_cols               = 5,
+	.rows_gpio_start	= PM8921_GPIO_PM_TO_SYS(9),
+	.cols_gpio_start	= PM8921_GPIO_PM_TO_SYS(1),
+	.debounce_ms            = 15,
+	.scan_delay_ms          = 32,
+	.row_hold_ns            = 91500,
+	.wakeup                 = 1,
+	.keymap_data            = &keymap_data,
+};
+
+static const unsigned int keymap_sim[] = {
+	KEY(0, 0, KEY_7),
+	KEY(0, 1, KEY_DOWN),
+	KEY(0, 2, KEY_UP),
+	KEY(0, 3, KEY_RIGHT),
+	KEY(0, 4, KEY_ENTER),
+	KEY(0, 5, KEY_L),
+	KEY(0, 6, KEY_BACK),
+	KEY(0, 7, KEY_M),
+
+	KEY(1, 0, KEY_LEFT),
+	KEY(1, 1, KEY_SEND),
+	KEY(1, 2, KEY_1),
+	KEY(1, 3, KEY_4),
+	KEY(1, 4, KEY_CLEAR),
+	KEY(1, 5, KEY_MSDOS),
+	KEY(1, 6, KEY_SPACE),
+	KEY(1, 7, KEY_COMMA),
+
+	KEY(2, 0, KEY_6),
+	KEY(2, 1, KEY_5),
+	KEY(2, 2, KEY_8),
+	KEY(2, 3, KEY_3),
+	KEY(2, 4, KEY_NUMERIC_STAR),
+	KEY(2, 5, KEY_UP),
+	KEY(2, 6, KEY_DOWN),
+	KEY(2, 7, KEY_LEFTSHIFT),
+
+	KEY(3, 0, KEY_9),
+	KEY(3, 1, KEY_NUMERIC_POUND),
+	KEY(3, 2, KEY_0),
+	KEY(3, 3, KEY_2),
+	KEY(3, 4, KEY_SLEEP),
+	KEY(3, 5, KEY_F1),
+	KEY(3, 6, KEY_F2),
+	KEY(3, 7, KEY_F3),
+
+	KEY(4, 0, KEY_BACK),
+	KEY(4, 1, KEY_HOME),
+	KEY(4, 2, KEY_MENU),
+	KEY(4, 3, KEY_VOLUMEUP),
+	KEY(4, 4, KEY_VOLUMEDOWN),
+	KEY(4, 5, KEY_F4),
+	KEY(4, 6, KEY_F5),
+	KEY(4, 7, KEY_F6),
+
+	KEY(5, 0, KEY_R),
+	KEY(5, 1, KEY_T),
+	KEY(5, 2, KEY_Y),
+	KEY(5, 3, KEY_LEFTALT),
+	KEY(5, 4, KEY_KPENTER),
+	KEY(5, 5, KEY_Q),
+	KEY(5, 6, KEY_W),
+	KEY(5, 7, KEY_E),
+
+	KEY(6, 0, KEY_F),
+	KEY(6, 1, KEY_G),
+	KEY(6, 2, KEY_H),
+	KEY(6, 3, KEY_CAPSLOCK),
+	KEY(6, 4, KEY_PAGEUP),
+	KEY(6, 5, KEY_A),
+	KEY(6, 6, KEY_S),
+	KEY(6, 7, KEY_D),
+
+	KEY(7, 0, KEY_V),
+	KEY(7, 1, KEY_B),
+	KEY(7, 2, KEY_N),
+	KEY(7, 3, KEY_MENU),
+	KEY(7, 4, KEY_PAGEDOWN),
+	KEY(7, 5, KEY_Z),
+	KEY(7, 6, KEY_X),
+	KEY(7, 7, KEY_C),
+
+	KEY(8, 0, KEY_P),
+	KEY(8, 1, KEY_J),
+	KEY(8, 2, KEY_K),
+	KEY(8, 3, KEY_INSERT),
+	KEY(8, 4, KEY_LINEFEED),
+	KEY(8, 5, KEY_U),
+	KEY(8, 6, KEY_I),
+	KEY(8, 7, KEY_O),
+
+	KEY(9, 0, KEY_4),
+	KEY(9, 1, KEY_5),
+	KEY(9, 2, KEY_6),
+	KEY(9, 3, KEY_7),
+	KEY(9, 4, KEY_8),
+	KEY(9, 5, KEY_1),
+	KEY(9, 6, KEY_2),
+	KEY(9, 7, KEY_3),
+
+	KEY(10, 0, KEY_F7),
+	KEY(10, 1, KEY_F8),
+	KEY(10, 2, KEY_F9),
+	KEY(10, 3, KEY_F10),
+	KEY(10, 4, KEY_FN),
+	KEY(10, 5, KEY_9),
+	KEY(10, 6, KEY_0),
+	KEY(10, 7, KEY_DOT),
+
+	KEY(11, 0, KEY_LEFTCTRL),
+	KEY(11, 1, KEY_F11),
+	KEY(11, 2, KEY_ENTER),
+	KEY(11, 3, KEY_SEARCH),
+	KEY(11, 4, KEY_DELETE),
+	KEY(11, 5, KEY_RIGHT),
+	KEY(11, 6, KEY_LEFT),
+	KEY(11, 7, KEY_RIGHTSHIFT),
+	KEY(0, 0, KEY_VOLUMEUP),
+	KEY(0, 1, KEY_VOLUMEDOWN),
+	KEY(0, 2, KEY_CAMERA_SNAPSHOT),
+	KEY(0, 3, KEY_CAMERA_FOCUS),
+};
+
+static int pm8921_therm_mitigation[] = {
+	1100,
+	700,
+	600,
+	325,
+};
+
+static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
+	.safety_time		= 180,
+	.update_time		= 60000,
+	.max_voltage		= 4200,
+	.min_voltage		= 3200,
+	.resume_voltage_delta	= 100,
+	.term_current		= 100,
+	.cool_temp		= 10,
+	.warm_temp		= 40,
+	.temp_check_period	= 1,
+	.max_bat_chg_current	= 1100,
+	.cool_bat_chg_current	= 350,
+	.warm_bat_chg_current	= 350,
+	.cool_bat_voltage	= 4100,
+	.warm_bat_voltage	= 4100,
+	.thermal_mitigation	= pm8921_therm_mitigation,
+	.thermal_levels		= ARRAY_SIZE(pm8921_therm_mitigation),
+};
+
+static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
+	.priority		= 0,
+};
+
+static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
+	.r_sense		= 10,
+	.i_test			= 2500,
+	.v_failure		= 3000,
+	.calib_delay_ms		= 600000,
+};
+
+#define	PM8921_LC_LED_MAX_CURRENT	4	/* I = 4mA */
+#define PM8XXX_LED_PWM_PERIOD		1000
+#define PM8XXX_LED_PWM_DUTY_MS		20
+/**
+ * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
+ * driven using PWM feature.
+ */
+#define PM8XXX_PWM_CHANNEL_NONE		-1
+
+static struct led_info pm8921_led_info[] = {
+	[0] = {
+		.name			= "led:battery_charging",
+		.default_trigger	= "battery-charging",
+	},
+	[1] = {
+		.name			= "led:battery_full",
+		.default_trigger	= "battery-full",
+	},
+};
+
+static struct led_platform_data pm8921_led_core_pdata = {
+	.num_leds = ARRAY_SIZE(pm8921_led_info),
+	.leds = pm8921_led_info,
+};
+
+static int pm8921_led0_pwm_duty_pcts[56] = {
+		1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+		40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
+		80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
+		92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
+		58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
+		14, 10, 6, 4, 1
+};
+
+static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
+	.duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
+	.num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
+	.duty_ms = PM8XXX_LED_PWM_DUTY_MS,
+	.start_idx = 0,
+};
+
+static struct pm8xxx_led_config pm8921_led_configs[] = {
+	[0] = {
+		.id = PM8XXX_ID_LED_0,
+		.mode = PM8XXX_LED_MODE_PWM2,
+		.max_current = PM8921_LC_LED_MAX_CURRENT,
+		.pwm_channel = 5,
+		.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
+		.pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
+	},
+	[1] = {
+		.id = PM8XXX_ID_LED_1,
+		.mode = PM8XXX_LED_MODE_PWM1,
+		.max_current = PM8921_LC_LED_MAX_CURRENT,
+		.pwm_channel = 4,
+		.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
+	},
+};
+
+static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
+		.led_core = &pm8921_led_core_pdata,
+		.configs = pm8921_led_configs,
+		.num_configs = ARRAY_SIZE(pm8921_led_configs),
+};
+
+static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
+	.r_sense		= 10,
+};
+
+static struct pm8921_platform_data pm8921_platform_data __devinitdata = {
+	.irq_pdata		= &pm8xxx_irq_pdata,
+	.gpio_pdata		= &pm8xxx_gpio_pdata,
+	.mpp_pdata		= &pm8xxx_mpp_pdata,
+	.rtc_pdata              = &pm8xxx_rtc_pdata,
+	.pwrkey_pdata		= &pm8xxx_pwrkey_pdata,
+	.keypad_pdata		= &keypad_data,
+	.misc_pdata		= &pm8xxx_misc_pdata,
+	.regulator_pdatas	= msm_pm8921_regulator_pdata,
+	.charger_pdata		= &pm8921_chg_pdata,
+	.bms_pdata		= &pm8921_bms_pdata,
+	.adc_pdata		= &pm8xxx_adc_pdata,
+	.leds_pdata		= &pm8xxx_leds_pdata,
+	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
+};
+
+static struct msm_ssbi_platform_data msm8960_ssbi_pm8921_pdata __devinitdata = {
+	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+	.slave	= {
+		.name			= "pm8921-core",
+		.platform_data		= &pm8921_platform_data,
+	},
+};
+
+void __init msm8930_init_pmic(void)
+{
+	pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
+	msm8960_device_ssbi_pm8921.dev.platform_data =
+				&msm8960_ssbi_pm8921_pdata;
+	pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
+
+	/* Simulator supports a QWERTY keypad */
+}
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
new file mode 100644
index 0000000..032d3d0
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -0,0 +1,268 @@
+/* Copyright (c) 2011, 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/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <asm/mach-types.h>
+#include <asm/mach/mmc.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8930.h"
+
+/* MSM8960 has 5 SDCC controllers */
+enum sdcc_controllers {
+	SDCC1,
+	SDCC2,
+	SDCC3,
+	SDCC4,
+	SDCC5,
+	MAX_SDCC_CONTROLLER
+};
+
+/* All SDCC controllers require VDD/VCC voltage */
+static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.name = "sdc_vdd",
+		.high_vol_level = 2950000,
+		.low_vol_level = 2950000,
+		.always_on = 1,
+		.lpm_sup = 1,
+		.lpm_uA = 9000,
+		.hpm_uA = 200000, /* 200mA */
+	},
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.name = "sdc_vdd",
+		.high_vol_level = 2950000,
+		.low_vol_level = 2950000,
+		.hpm_uA = 600000, /* 600mA */
+	}
+};
+
+/* Only slots having eMMC card will require VCCQ voltage */
+static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.name = "sdc_vccq",
+		.always_on = 1,
+		.high_vol_level = 1800000,
+		.low_vol_level = 1800000,
+		.hpm_uA = 200000, /* 200mA */
+	}
+};
+
+/* All SDCC controllers may require voting for VDD PAD voltage */
+static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.name = "sdc_vddp",
+		.high_vol_level = 2950000,
+		.low_vol_level = 1850000,
+		.always_on = 1,
+		.lpm_sup = 1,
+		/* Max. Active current required is 16 mA */
+		.hpm_uA = 16000,
+		/*
+		 * Sleep current required is ~300 uA. But min. vote can be
+		 * in terms of mA (min. 1 mA). So let's vote for 2 mA
+		 * during sleep.
+		 */
+		.lpm_uA = 2000,
+	}
+};
+
+static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.vdd_data = &mmc_vdd_reg_data[SDCC1],
+		.vccq_data = &mmc_vccq_reg_data[SDCC1],
+	},
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.vdd_data = &mmc_vdd_reg_data[SDCC3],
+		.vddp_data = &mmc_vddp_reg_data[SDCC3],
+	}
+};
+
+/* SDC1 pad data */
+static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
+	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
+	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
+	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
+};
+
+static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
+	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
+};
+
+static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
+	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
+	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
+	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
+	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
+};
+
+/* SDC3 pad data */
+static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
+	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
+	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
+	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
+};
+
+static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
+	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
+};
+
+static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
+	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
+	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
+	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
+	/*
+	 * SDC3 CMD line should be PULLed UP otherwise fluid platform will
+	 * see transitions (1 -> 0 and 0 -> 1) on card detection line,
+	 * which would result in false card detection interrupts.
+	 */
+	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
+	/*
+	 * Keeping DATA lines status to PULL UP will make sure that
+	 * there is no current leak during sleep if external pull up
+	 * is connected to DATA lines.
+	 */
+	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.on = sdc1_pad_pull_on_cfg,
+		.off = sdc1_pad_pull_off_cfg,
+		.size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
+	},
+	[SDCC3] = {
+		.on = sdc3_pad_pull_on_cfg,
+		.off = sdc3_pad_pull_off_cfg,
+		.size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
+	},
+};
+
+static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.on = sdc1_pad_drv_on_cfg,
+		.off = sdc1_pad_drv_off_cfg,
+		.size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
+	},
+	[SDCC3] = {
+		.on = sdc3_pad_drv_on_cfg,
+		.off = sdc3_pad_drv_off_cfg,
+		.size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
+	},
+};
+
+static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.pull = &mmc_pad_pull_data[SDCC1],
+		.drv = &mmc_pad_drv_data[SDCC1]
+	},
+	[SDCC3] = {
+		.pull = &mmc_pad_pull_data[SDCC3],
+		.drv = &mmc_pad_drv_data[SDCC3]
+	},
+};
+
+static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.pad_data = &mmc_pad_data[SDCC1],
+	},
+	[SDCC3] = {
+		.pad_data = &mmc_pad_data[SDCC3],
+	},
+};
+
+static unsigned int sdc1_sup_clk_rates[] = {
+	400000, 24000000, 48000000
+};
+
+static unsigned int sdc3_sup_clk_rates[] = {
+	400000, 24000000, 48000000, 96000000
+};
+
+#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
+static struct mmc_platform_data msm8960_sdc1_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
+	.mmc_bus_width  = MMC_CAP_8_BIT_DATA,
+#else
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+#endif
+	.sup_clk_table	= sdc1_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
+	.pclk_src_dfab	= 1,
+	.nonremovable	= 1,
+	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
+	.pin_data	= &mmc_slot_pin_data[SDCC1]
+};
+#endif
+
+#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
+static struct mmc_platform_data msm8960_sdc3_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+	.sup_clk_table	= sdc3_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
+	.pclk_src_dfab	= 1,
+#ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
+	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
+#endif
+	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
+	.pin_data	= &mmc_slot_pin_data[SDCC3],
+#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
+	.status_gpio	= PM8921_GPIO_PM_TO_SYS(26),
+	.status_irq	= PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
+	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+#endif
+	.xpc_cap	= 1,
+	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+			MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
+			MMC_CAP_MAX_CURRENT_600)
+};
+#endif
+
+void __init msm8930_init_mmc(void)
+{
+#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
+	/* SDC1 : eMMC card connected */
+	msm_add_sdcc(1, &msm8960_sdc1_data);
+#endif
+#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
+	/* SDC3: External card slot */
+	msm_add_sdcc(3, &msm8960_sdc3_data);
+#endif
+}
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
new file mode 100644
index 0000000..cc020b5
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930.c
@@ -0,0 +1,1985 @@
+/* Copyright (c) 2011, 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/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/i2c/sx150x.h>
+#include <linux/i2c/isl9519.h>
+#include <linux/gpio.h>
+#include <linux/msm_ssbi.h>
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <linux/slimbus/slimbus.h>
+#include <linux/bootmem.h>
+#include <linux/msm_kgsl.h>
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+#include <linux/cyttsp.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_data/qcom_crypto_device.h>
+#include <linux/platform_data/qcom_wcnss_device.h>
+#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/msm_tsens.h>
+#include <linux/ks8851.h>
+#include <linux/i2c/isa1200.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/mmc.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_spi.h>
+#ifdef CONFIG_USB_MSM_OTG_72K
+#include <mach/msm_hsusb.h>
+#else
+#include <linux/usb/msm_hsusb.h>
+#endif
+#include <linux/usb/android.h>
+#include <mach/usbdiag.h>
+#include <mach/socinfo.h>
+#include <mach/rpm.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_memtypes.h>
+#include <mach/dma.h>
+#include <mach/msm_xo.h>
+#include <mach/restart.h>
+
+#ifdef CONFIG_WCD9310_CODEC
+#include <linux/slimbus/slimbus.h>
+#include <linux/mfd/wcd9310/core.h>
+#include <linux/mfd/wcd9310/pdata.h>
+#endif
+
+#include <linux/ion.h>
+#include <mach/ion.h>
+#include <mach/mdm2.h>
+
+#include "timer.h"
+#include "devices.h"
+#include "devices-msm8x60.h"
+#include "spm.h"
+#include "board-8930.h"
+#include "pm.h"
+#include "cpuidle.h"
+#include "rpm_resources.h"
+#include "mpm.h"
+#include "acpuclock.h"
+#include "rpm_log.h"
+#include "smd_private.h"
+#include "pm-boot.h"
+#include "msm_watchdog.h"
+
+static struct platform_device msm_fm_platform_init = {
+	.name = "iris_fm",
+	.id   = -1,
+};
+
+#define KS8851_RST_GPIO		89
+#define KS8851_IRQ_GPIO		90
+#define HAP_SHIFT_LVL_OE_GPIO	47
+
+#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
+
+struct sx150x_platform_data msm8930_sx150x_data[] = {
+	[SX150X_CAM] = {
+		.gpio_base         = GPIO_CAM_EXPANDER_BASE,
+		.oscio_is_gpo      = false,
+		.io_pullup_ena     = 0x0,
+		.io_pulldn_ena     = 0xc0,
+		.io_open_drain_ena = 0x0,
+		.irq_summary       = -1,
+	},
+};
+
+#endif
+
+#define MSM_PMEM_ADSP_SIZE         0x3800000
+#define MSM_PMEM_AUDIO_SIZE        0x28B000
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
+#else
+#define MSM_PMEM_SIZE 0x1C00000 /* 28 Mbytes */
+#endif
+
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
+#define MSM_ION_EBI_SIZE	(MSM_PMEM_SIZE + 0x600000)
+#define MSM_ION_ADSP_SIZE	MSM_PMEM_ADSP_SIZE
+#define MSM_ION_HEAP_NUM	4
+#else
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
+#define MSM_ION_HEAP_NUM	2
+#endif
+
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
+static int __init pmem_kernel_ebi1_size_setup(char *p)
+{
+	pmem_kernel_ebi1_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+static unsigned pmem_size = MSM_PMEM_SIZE;
+static int __init pmem_size_setup(char *p)
+{
+	pmem_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_size", pmem_size_setup);
+
+static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
+
+static int __init pmem_adsp_size_setup(char *p)
+{
+	pmem_adsp_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_adsp_size", pmem_adsp_size_setup);
+
+static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE;
+
+static int __init pmem_audio_size_setup(char *p)
+{
+	pmem_audio_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_audio_size", pmem_audio_size_setup);
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+static struct android_pmem_platform_data android_pmem_pdata = {
+	.name = "pmem",
+	.allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
+	.cached = 1,
+	.memory_type = MEMTYPE_EBI1,
+};
+
+static struct platform_device android_pmem_device = {
+	.name = "android_pmem",
+	.id = 0,
+	.dev = {.platform_data = &android_pmem_pdata},
+};
+
+static struct android_pmem_platform_data android_pmem_adsp_pdata = {
+	.name = "pmem_adsp",
+	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
+	.cached = 0,
+	.memory_type = MEMTYPE_EBI1,
+};
+static struct platform_device android_pmem_adsp_device = {
+	.name = "android_pmem",
+	.id = 2,
+	.dev = { .platform_data = &android_pmem_adsp_pdata },
+};
+#endif
+
+static struct android_pmem_platform_data android_pmem_audio_pdata = {
+	.name = "pmem_audio",
+	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
+	.cached = 0,
+	.memory_type = MEMTYPE_EBI1,
+};
+
+static struct platform_device android_pmem_audio_device = {
+	.name = "android_pmem",
+	.id = 4,
+	.dev = { .platform_data = &android_pmem_audio_pdata },
+};
+#endif
+
+#define DSP_RAM_BASE_8960 0x8da00000
+#define DSP_RAM_SIZE_8960 0x1800000
+static int dspcrashd_pdata_8960 = 0xDEADDEAD;
+
+static struct resource resources_dspcrashd_8960[] = {
+	{
+		.name   = "msm_dspcrashd",
+		.start  = DSP_RAM_BASE_8960,
+		.end    = DSP_RAM_BASE_8960 + DSP_RAM_SIZE_8960,
+		.flags  = IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device msm_device_dspcrashd_8960 = {
+	.name           = "msm_dspcrashd",
+	.num_resources  = ARRAY_SIZE(resources_dspcrashd_8960),
+	.resource       = resources_dspcrashd_8960,
+	.dev = { .platform_data = &dspcrashd_pdata_8960 },
+};
+
+static struct memtype_reserve msm8930_reserve_table[] __initdata = {
+	[MEMTYPE_SMI] = {
+	},
+	[MEMTYPE_EBI0] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+	[MEMTYPE_EBI1] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
+
+static void __init size_pmem_devices(void)
+{
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	android_pmem_adsp_pdata.size = pmem_adsp_size;
+	android_pmem_pdata.size = pmem_size;
+#endif
+	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
+#endif
+}
+
+static void __init reserve_memory_for(struct android_pmem_platform_data *p)
+{
+	msm8930_reserve_table[p->memory_type].size += p->size;
+}
+
+static void __init reserve_pmem_memory(void)
+{
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	reserve_memory_for(&android_pmem_adsp_pdata);
+	reserve_memory_for(&android_pmem_pdata);
+#endif
+	reserve_memory_for(&android_pmem_audio_pdata);
+	msm8930_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
+#endif
+}
+
+static int msm8930_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+#ifdef CONFIG_ION_MSM
+static struct ion_platform_data ion_pdata = {
+	.nr = MSM_ION_HEAP_NUM,
+	.heaps = {
+		{
+			.id	= ION_HEAP_SYSTEM_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM,
+			.name	= ION_KMALLOC_HEAP_NAME,
+		},
+		{
+			.id	= ION_HEAP_SYSTEM_CONTIG_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM_CONTIG,
+			.name	= ION_VMALLOC_HEAP_NAME,
+		},
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		{
+			.id	= ION_HEAP_EBI_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_EBI1_HEAP_NAME,
+			.size	= MSM_ION_EBI_SIZE,
+			.memory_type = ION_EBI_TYPE,
+		},
+		{
+			.id	= ION_HEAP_ADSP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_ADSP_HEAP_NAME,
+			.size	= MSM_ION_ADSP_SIZE,
+			.memory_type = ION_EBI_TYPE,
+		},
+#endif
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+#endif
+
+static void reserve_ion_memory(void)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_EBI_SIZE;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_ADSP_SIZE;
+#endif
+}
+static void __init msm8930_calculate_reserve_sizes(void)
+{
+	size_pmem_devices();
+	reserve_pmem_memory();
+	reserve_ion_memory();
+}
+
+static struct reserve_info msm8930_reserve_info __initdata = {
+	.memtype_reserve_table = msm8930_reserve_table,
+	.calculate_reserve_sizes = msm8930_calculate_reserve_sizes,
+	.paddr_to_memtype = msm8930_paddr_to_memtype,
+};
+
+static int msm8930_memory_bank_size(void)
+{
+	return 1<<29;
+}
+
+static void __init locate_unstable_memory(void)
+{
+	struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
+	unsigned long bank_size;
+	unsigned long low, high;
+
+	bank_size = msm8930_memory_bank_size();
+	low = meminfo.bank[0].start;
+	high = mb->start + mb->size;
+
+	/* Check if 32 bit overflow occured */
+	if (high < mb->start)
+		high = ~0UL;
+
+	low &= ~(bank_size - 1);
+
+	if (high - low <= bank_size)
+		return;
+	msm8930_reserve_info.low_unstable_address = low + bank_size;
+	/* To avoid overflow of u32 compute max_unstable_size
+	 * by first subtracting low from mb->start)
+	 * */
+	msm8930_reserve_info.max_unstable_size = (mb->start - low) +
+						mb->size - bank_size;
+
+	msm8930_reserve_info.bank_size = bank_size;
+	pr_info("low unstable address %lx max size %lx bank size %lx\n",
+		msm8930_reserve_info.low_unstable_address,
+		msm8930_reserve_info.max_unstable_size,
+		msm8930_reserve_info.bank_size);
+}
+
+static void __init place_movable_zone(void)
+{
+	movable_reserved_start = msm8930_reserve_info.low_unstable_address;
+	movable_reserved_size = msm8930_reserve_info.max_unstable_size;
+	pr_info("movable zone start %lx size %lx\n",
+		movable_reserved_start, movable_reserved_size);
+}
+
+static void __init msm8930_early_memory(void)
+{
+	reserve_info = &msm8930_reserve_info;
+	locate_unstable_memory();
+	place_movable_zone();
+}
+
+static void __init msm8930_reserve(void)
+{
+	msm_reserve();
+}
+
+static int msm8930_change_memory_power(u64 start, u64 size,
+	int change_type)
+{
+	return soc_change_memory_power(start, size, change_type);
+}
+
+static void __init msm8930_allocate_memory_regions(void)
+{
+	msm8930_allocate_fb_region();
+}
+
+#ifdef CONFIG_WCD9310_CODEC
+
+#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_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 tabla_pdata tabla_platform_data = {
+	.slimbus_slave_device = {
+		.name = "tabla-slave",
+		.e_addr = {0, 0, 0x10, 0, 0x17, 2},
+	},
+	.irq = MSM_GPIO_TO_INT(62),
+	.irq_base = TABLA_INTERRUPT_BASE,
+	.num_irqs = NR_TABLA_IRQS,
+	.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+	.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,
+	}
+};
+
+static struct slim_device msm_slim_tabla = {
+	.name = "tabla-slim",
+	.e_addr = {0, 1, 0x10, 0, 0x17, 2},
+	.dev = {
+		.platform_data = &tabla_platform_data,
+	},
+};
+
+static struct tabla_pdata tabla20_platform_data = {
+	.slimbus_slave_device = {
+		.name = "tabla-slave",
+		.e_addr = {0, 0, 0x60, 0, 0x17, 2},
+	},
+	.irq = MSM_GPIO_TO_INT(62),
+	.irq_base = TABLA_INTERRUPT_BASE,
+	.num_irqs = NR_TABLA_IRQS,
+	.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+	.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,
+	}
+};
+
+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[] = {
+#ifdef CONFIG_WCD9310_CODEC
+	{
+		.bus_num = 1,
+		.slim_slave = &msm_slim_tabla,
+	},
+	{
+		.bus_num = 1,
+		.slim_slave = &msm_slim_tabla20,
+	},
+#endif
+	/* add more slimbus slaves as needed */
+};
+
+#define MSM_WCNSS_PHYS	0x03000000
+#define MSM_WCNSS_SIZE	0x280000
+
+static struct resource resources_wcnss_wlan[] = {
+	{
+		.start	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+		.end	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+		.name	= "wcnss_wlanrx_irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+		.end	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+		.name	= "wcnss_wlantx_irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_WCNSS_PHYS,
+		.end	= MSM_WCNSS_PHYS + MSM_WCNSS_SIZE - 1,
+		.name	= "wcnss_mmio",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 84,
+		.end	= 88,
+		.name	= "wcnss_gpios_5wire",
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct qcom_wcnss_opts qcom_wcnss_pdata = {
+	.has_48mhz_xo	= 1,
+};
+
+static struct platform_device msm_device_wcnss_wlan = {
+	.name		= "wcnss_wlan",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(resources_wcnss_wlan),
+	.resource	= resources_wcnss_wlan,
+	.dev		= {.platform_data = &qcom_wcnss_pdata},
+};
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+
+#define QCE_SIZE		0x10000
+#define QCE_0_BASE		0x18500000
+
+#define QCE_HW_KEY_SUPPORT	0
+#define QCE_SHA_HMAC_SUPPORT	1
+#define QCE_SHARE_CE_RESOURCE	1
+#define QCE_CE_SHARED		0
+
+static struct resource qcrypto_resources[] = {
+	[0] = {
+		.start = QCE_0_BASE,
+		.end = QCE_0_BASE + QCE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.name = "crypto_channels",
+		.start = DMOV_CE_IN_CHAN,
+		.end = DMOV_CE_OUT_CHAN,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.name = "crypto_crci_in",
+		.start = DMOV_CE_IN_CRCI,
+		.end = DMOV_CE_IN_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.name = "crypto_crci_out",
+		.start = DMOV_CE_OUT_CRCI,
+		.end = DMOV_CE_OUT_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct resource qcedev_resources[] = {
+	[0] = {
+		.start = QCE_0_BASE,
+		.end = QCE_0_BASE + QCE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.name = "crypto_channels",
+		.start = DMOV_CE_IN_CHAN,
+		.end = DMOV_CE_OUT_CHAN,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.name = "crypto_crci_in",
+		.start = DMOV_CE_IN_CRCI,
+		.end = DMOV_CE_IN_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.name = "crypto_crci_out",
+		.start = DMOV_CE_OUT_CRCI,
+		.end = DMOV_CE_OUT_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+
+static struct msm_ce_hw_support qcrypto_ce_hw_suppport = {
+	.ce_shared = QCE_CE_SHARED,
+	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
+	.hw_key_support = QCE_HW_KEY_SUPPORT,
+	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
+};
+
+static struct platform_device qcrypto_device = {
+	.name		= "qcrypto",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(qcrypto_resources),
+	.resource	= qcrypto_resources,
+	.dev		= {
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &qcrypto_ce_hw_suppport,
+	},
+};
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+
+static struct msm_ce_hw_support qcedev_ce_hw_suppport = {
+	.ce_shared = QCE_CE_SHARED,
+	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
+	.hw_key_support = QCE_HW_KEY_SUPPORT,
+	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
+};
+
+static struct platform_device qcedev_device = {
+	.name		= "qce",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(qcedev_resources),
+	.resource	= qcedev_resources,
+	.dev		= {
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &qcedev_ce_hw_suppport,
+	},
+};
+#endif
+
+#define MDM2AP_ERRFATAL			70
+#define AP2MDM_ERRFATAL			95
+#define MDM2AP_STATUS			69
+#define AP2MDM_STATUS			94
+#define AP2MDM_PMIC_RESET_N		80
+#define AP2MDM_KPDPWR_N			81
+
+static struct resource mdm_resources[] = {
+	{
+		.start	= MDM2AP_ERRFATAL,
+		.end	= MDM2AP_ERRFATAL,
+		.name	= "MDM2AP_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_ERRFATAL,
+		.end	= AP2MDM_ERRFATAL,
+		.name	= "AP2MDM_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= MDM2AP_STATUS,
+		.end	= MDM2AP_STATUS,
+		.name	= "MDM2AP_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_STATUS,
+		.end	= AP2MDM_STATUS,
+		.name	= "AP2MDM_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_PMIC_RESET_N,
+		.end	= AP2MDM_PMIC_RESET_N,
+		.name	= "AP2MDM_PMIC_RESET_N",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_KPDPWR_N,
+		.end	= AP2MDM_KPDPWR_N,
+		.name	= "AP2MDM_KPDPWR_N",
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct mdm_platform_data mdm_platform_data = {
+	.mdm_version = "2.5",
+};
+
+static struct platform_device mdm_device = {
+	.name		= "mdm2_modem",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(mdm_resources),
+	.resource	= mdm_resources,
+	.dev		= {
+		.platform_data = &mdm_platform_data,
+	},
+};
+
+static struct platform_device *mdm_devices[] __initdata = {
+	&mdm_device,
+};
+
+#define MSM_SHARED_RAM_PHYS 0x80000000
+
+static void __init msm8930_map_io(void)
+{
+	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
+	msm_map_msm8930_io();
+
+	if (socinfo_init() < 0)
+		pr_err("socinfo_init() failed!\n");
+}
+
+static void __init msm8930_init_irq(void)
+{
+	unsigned int i;
+
+	msm_mpm_irq_extn_init();
+	gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
+						(void *)MSM_QGIC_CPU_BASE);
+
+	/* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
+	writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
+
+	writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
+	mb();
+
+	/* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
+	 * as they are configured as level, which does not play nice with
+	 * handle_percpu_irq.
+	 */
+	for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
+		if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
+			irq_set_handler(i, handle_percpu_irq);
+	}
+}
+
+static void __init msm8930_init_buses(void)
+{
+#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;
+#endif
+}
+
+static struct msm_spi_platform_data msm8960_qup_spi_gsbi1_pdata = {
+	.max_clock_speed = 15060000,
+};
+
+#ifdef CONFIG_USB_MSM_OTG_72K
+static struct msm_otg_platform_data msm_otg_pdata;
+#else
+#define USB_5V_EN		42
+static void msm_hsusb_vbus_power(bool on)
+{
+	int rc;
+	static bool vbus_is_on;
+	static struct regulator *mvs_otg_switch;
+
+	if (vbus_is_on == on)
+		return;
+
+	if (on) {
+		mvs_otg_switch = regulator_get(&msm8960_device_otg.dev,
+					       "vbus_otg");
+		if (IS_ERR(mvs_otg_switch)) {
+			pr_err("Unable to get mvs_otg_switch\n");
+			return;
+		}
+
+		rc = gpio_request(PM8921_GPIO_PM_TO_SYS(USB_5V_EN),
+						"usb_5v_en");
+		if (rc < 0) {
+			pr_err("failed to request usb_5v_en gpio\n");
+			goto put_mvs_otg;
+		}
+
+		rc = gpio_direction_output(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 1);
+		if (rc) {
+			pr_err("%s: unable to set_direction for gpio [%d]\n",
+				__func__, PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
+			goto free_usb_5v_en;
+		}
+
+		if (regulator_enable(mvs_otg_switch)) {
+			pr_err("unable to enable mvs_otg_switch\n");
+			goto err_ldo_gpio_set_dir;
+		}
+
+		vbus_is_on = true;
+		return;
+	}
+	regulator_disable(mvs_otg_switch);
+err_ldo_gpio_set_dir:
+	gpio_set_value(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
+free_usb_5v_en:
+	gpio_free(PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
+put_mvs_otg:
+	regulator_put(mvs_otg_switch);
+	vbus_is_on = false;
+}
+
+static struct msm_otg_platform_data msm_otg_pdata = {
+	.mode			= USB_OTG,
+	.otg_control		= OTG_PMIC_CONTROL,
+	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
+	.pclk_src_name		= "dfab_usb_hs_clk",
+	.pmic_id_irq		= PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
+	.vbus_power		= msm_hsusb_vbus_power,
+	.power_budget		= 750,
+};
+#endif
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+#define HSIC_HUB_RESET_GPIO	91
+static struct msm_hsic_host_platform_data msm_hsic_pdata = {
+	.strobe		= 150,
+	.data		= 151,
+};
+#else
+static struct msm_hsic_host_platform_data msm_hsic_pdata;
+#endif
+
+#define PID_MAGIC_ID		0x71432909
+#define SERIAL_NUM_MAGIC_ID	0x61945374
+#define SERIAL_NUMBER_LENGTH	127
+#define DLOAD_USB_BASE_ADD	0x2A03F0C8
+
+struct magic_num_struct {
+	uint32_t pid;
+	uint32_t serial_num;
+};
+
+struct dload_struct {
+	uint32_t	reserved1;
+	uint32_t	reserved2;
+	uint32_t	reserved3;
+	uint16_t	reserved4;
+	uint16_t	pid;
+	char		serial_number[SERIAL_NUMBER_LENGTH];
+	uint16_t	reserved5;
+	struct magic_num_struct magic_struct;
+};
+
+static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
+{
+	struct dload_struct __iomem *dload = 0;
+
+	dload = ioremap(DLOAD_USB_BASE_ADD, sizeof(*dload));
+	if (!dload) {
+		pr_err("%s: cannot remap I/O memory region: %08x\n",
+					__func__, DLOAD_USB_BASE_ADD);
+		return -ENXIO;
+	}
+
+	pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
+				__func__, dload, pid, snum);
+	/* update pid */
+	dload->magic_struct.pid = PID_MAGIC_ID;
+	dload->pid = pid;
+
+	/* update serial number */
+	dload->magic_struct.serial_num = 0;
+	if (!snum) {
+		memset(dload->serial_number, 0, SERIAL_NUMBER_LENGTH);
+		goto out;
+	}
+
+	dload->magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
+	strlcpy(dload->serial_number, snum, SERIAL_NUMBER_LENGTH);
+out:
+	iounmap(dload);
+	return 0;
+}
+
+static struct android_usb_platform_data android_usb_pdata = {
+	.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
+};
+
+static struct platform_device android_usb_device = {
+	.name	= "android_usb",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &android_usb_pdata,
+	},
+};
+
+static uint8_t spm_wfi_cmd_sequence[] __initdata = {
+			0x03, 0x0f,
+};
+
+static uint8_t spm_power_collapse_without_rpm[] __initdata = {
+			0x00, 0x24, 0x54, 0x10,
+			0x09, 0x03, 0x01,
+			0x10, 0x54, 0x30, 0x0C,
+			0x24, 0x30, 0x0f,
+};
+
+static uint8_t spm_power_collapse_with_rpm[] __initdata = {
+			0x00, 0x24, 0x54, 0x10,
+			0x09, 0x07, 0x01, 0x0B,
+			0x10, 0x54, 0x30, 0x0C,
+			0x24, 0x30, 0x0f,
+};
+
+static struct msm_spm_seq_entry msm_spm_seq_list[] __initdata = {
+	[0] = {
+		.mode = MSM_SPM_MODE_CLOCK_GATING,
+		.notify_rpm = false,
+		.cmd = spm_wfi_cmd_sequence,
+	},
+	[1] = {
+		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
+		.notify_rpm = false,
+		.cmd = spm_power_collapse_without_rpm,
+	},
+	[2] = {
+		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
+		.notify_rpm = true,
+		.cmd = spm_power_collapse_with_rpm,
+	},
+};
+
+static struct msm_spm_platform_data msm_spm_data[] __initdata = {
+	[0] = {
+		.reg_base_addr = MSM_SAW0_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
+		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
+#if defined(CONFIG_MSM_AVS_HW)
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
+#endif
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.vctl_timeout_us = 50,
+		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
+		.modes = msm_spm_seq_list,
+	},
+	[1] = {
+		.reg_base_addr = MSM_SAW1_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
+		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
+#if defined(CONFIG_MSM_AVS_HW)
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
+#endif
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.vctl_timeout_us = 50,
+		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
+		.modes = msm_spm_seq_list,
+	},
+};
+
+static uint8_t l2_spm_wfi_cmd_sequence[] __initdata = {
+			0x00, 0x20, 0x03, 0x20,
+			0x00, 0x0f,
+};
+
+static uint8_t l2_spm_gdhs_cmd_sequence[] __initdata = {
+			0x00, 0x20, 0x34, 0x64,
+			0x48, 0x07, 0x48, 0x20,
+			0x50, 0x64, 0x04, 0x34,
+			0x50, 0x0f,
+};
+static uint8_t l2_spm_power_off_cmd_sequence[] __initdata = {
+			0x00, 0x10, 0x34, 0x64,
+			0x48, 0x07, 0x48, 0x10,
+			0x50, 0x64, 0x04, 0x34,
+			0x50, 0x0F,
+};
+
+static struct msm_spm_seq_entry msm_spm_l2_seq_list[] __initdata = {
+	[0] = {
+		.mode = MSM_SPM_L2_MODE_RETENTION,
+		.notify_rpm = false,
+		.cmd = l2_spm_wfi_cmd_sequence,
+	},
+	[1] = {
+		.mode = MSM_SPM_L2_MODE_GDHS,
+		.notify_rpm = true,
+		.cmd = l2_spm_gdhs_cmd_sequence,
+	},
+	[2] = {
+		.mode = MSM_SPM_L2_MODE_POWER_COLLAPSE,
+		.notify_rpm = true,
+		.cmd = l2_spm_power_off_cmd_sequence,
+	},
+};
+
+static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
+	[0] = {
+		.reg_base_addr = MSM_SAW_L2_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A00020,
+		.modes = msm_spm_l2_seq_list,
+		.num_modes = ARRAY_SIZE(msm_spm_l2_seq_list),
+	},
+};
+
+#define PM_HAP_EN_GPIO		PM8921_GPIO_PM_TO_SYS(33)
+#define PM_HAP_LEN_GPIO		PM8921_GPIO_PM_TO_SYS(20)
+
+static struct msm_xo_voter *xo_handle_d1;
+
+static int isa1200_power(int on)
+{
+	int rc = 0;
+
+	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, !!on);
+
+	rc = on ? msm_xo_mode_vote(xo_handle_d1, MSM_XO_MODE_ON) :
+			msm_xo_mode_vote(xo_handle_d1, MSM_XO_MODE_OFF);
+	if (rc < 0) {
+		pr_err("%s: failed to %svote for TCXO D1 buffer%d\n",
+				__func__, on ? "" : "de-", rc);
+		goto err_xo_vote;
+	}
+
+	return 0;
+
+err_xo_vote:
+	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, !on);
+	return rc;
+}
+
+static int isa1200_dev_setup(bool enable)
+{
+	int rc = 0;
+
+	struct pm_gpio hap_gpio_config = {
+		.direction      = PM_GPIO_DIR_OUT,
+		.pull           = PM_GPIO_PULL_NO,
+		.out_strength   = PM_GPIO_STRENGTH_HIGH,
+		.function       = PM_GPIO_FUNC_NORMAL,
+		.inv_int_pol    = 0,
+		.vin_sel        = 2,
+		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+		.output_value   = 0,
+	};
+
+	if (enable == true) {
+		rc = pm8xxx_gpio_config(PM_HAP_EN_GPIO, &hap_gpio_config);
+		if (rc) {
+			pr_err("%s: pm8921 gpio %d config failed(%d)\n",
+					__func__, PM_HAP_EN_GPIO, rc);
+			return rc;
+		}
+
+		rc = pm8xxx_gpio_config(PM_HAP_LEN_GPIO, &hap_gpio_config);
+		if (rc) {
+			pr_err("%s: pm8921 gpio %d config failed(%d)\n",
+					__func__, PM_HAP_LEN_GPIO, rc);
+			return rc;
+		}
+
+		rc = gpio_request(HAP_SHIFT_LVL_OE_GPIO, "hap_shft_lvl_oe");
+		if (rc) {
+			pr_err("%s: unable to request gpio %d (%d)\n",
+					__func__, HAP_SHIFT_LVL_OE_GPIO, rc);
+			return rc;
+		}
+
+		rc = gpio_direction_output(HAP_SHIFT_LVL_OE_GPIO, 0);
+		if (rc) {
+			pr_err("%s: Unable to set direction\n", __func__);
+			goto free_gpio;
+		}
+
+		xo_handle_d1 = msm_xo_get(MSM_XO_TCXO_D1, "isa1200");
+		if (IS_ERR(xo_handle_d1)) {
+			rc = PTR_ERR(xo_handle_d1);
+			pr_err("%s: failed to get the handle for D1(%d)\n",
+							__func__, rc);
+			goto gpio_set_dir;
+		}
+	} else {
+		gpio_free(HAP_SHIFT_LVL_OE_GPIO);
+
+		msm_xo_put(xo_handle_d1);
+	}
+
+	return 0;
+
+gpio_set_dir:
+	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, 0);
+free_gpio:
+	gpio_free(HAP_SHIFT_LVL_OE_GPIO);
+	return rc;
+}
+
+static struct isa1200_regulator isa1200_reg_data[] = {
+	{
+		.name = "vcc_i2c",
+		.min_uV = ISA_I2C_VTG_MIN_UV,
+		.max_uV = ISA_I2C_VTG_MAX_UV,
+		.load_uA = ISA_I2C_CURR_UA,
+	},
+};
+
+static struct isa1200_platform_data isa1200_1_pdata = {
+	.name = "vibrator",
+	.dev_setup = isa1200_dev_setup,
+	.power_on = isa1200_power,
+	.hap_en_gpio = PM_HAP_EN_GPIO,
+	.hap_len_gpio = PM_HAP_LEN_GPIO,
+	.max_timeout = 15000,
+	.mode_ctrl = PWM_GEN_MODE,
+	.pwm_fd = {
+		.pwm_div = 256,
+	},
+	.is_erm = false,
+	.smart_en = true,
+	.ext_clk_en = true,
+	.chip_en = 1,
+	.regulator_info = isa1200_reg_data,
+	.num_regulators = ARRAY_SIZE(isa1200_reg_data),
+};
+
+static struct i2c_board_info msm_isa1200_board_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("isa1200_1", 0x90>>1),
+		.platform_data = &isa1200_1_pdata,
+	},
+};
+
+#define CYTTSP_TS_GPIO_IRQ		11
+#define CYTTSP_TS_SLEEP_GPIO		50
+#define CYTTSP_TS_RESOUT_N_GPIO		52
+
+/*virtual key support */
+static ssize_t tma340_vkeys_show(struct kobject *kobj,
+			struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, 200,
+	__stringify(EV_KEY) ":" __stringify(KEY_BACK) ":73:1120:97:97"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":230:1120:97:97"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":389:1120:97:97"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":544:1120:97:97"
+	"\n");
+}
+
+static struct kobj_attribute tma340_vkeys_attr = {
+	.attr = {
+		.mode = S_IRUGO,
+	},
+	.show = &tma340_vkeys_show,
+};
+
+static struct attribute *tma340_properties_attrs[] = {
+	&tma340_vkeys_attr.attr,
+	NULL
+};
+
+static struct attribute_group tma340_properties_attr_group = {
+	.attrs = tma340_properties_attrs,
+};
+
+
+static int cyttsp_platform_init(struct i2c_client *client)
+{
+	int rc = 0;
+	static struct kobject *tma340_properties_kobj;
+
+	tma340_vkeys_attr.attr.name = "virtualkeys.cyttsp-i2c";
+	tma340_properties_kobj = kobject_create_and_add("board_properties",
+								NULL);
+	if (tma340_properties_kobj)
+		rc = sysfs_create_group(tma340_properties_kobj,
+					&tma340_properties_attr_group);
+	if (!tma340_properties_kobj || rc)
+		pr_err("%s: failed to create board_properties\n",
+				__func__);
+
+	return 0;
+}
+
+static struct cyttsp_regulator regulator_data[] = {
+	{
+		.name = "vdd",
+		.min_uV = CY_TMA300_VTG_MIN_UV,
+		.max_uV = CY_TMA300_VTG_MAX_UV,
+		.hpm_load_uA = CY_TMA300_CURR_24HZ_UA,
+		.lpm_load_uA = CY_TMA300_SLEEP_CURR_UA,
+	},
+	/* TODO: Remove after runtime PM is enabled in I2C driver */
+	{
+		.name = "vcc_i2c",
+		.min_uV = CY_I2C_VTG_MIN_UV,
+		.max_uV = CY_I2C_VTG_MAX_UV,
+		.hpm_load_uA = CY_I2C_CURR_UA,
+		.lpm_load_uA = CY_I2C_SLEEP_CURR_UA,
+	},
+};
+
+static struct cyttsp_platform_data cyttsp_pdata = {
+	.panel_maxx = 634,
+	.panel_maxy = 1166,
+	.disp_maxx = 616,
+	.disp_maxy = 1023,
+	.disp_minx = 0,
+	.disp_miny = 16,
+	.flags = 0x01,
+	.gen = CY_GEN3,	/* or */
+	.use_st = CY_USE_ST,
+	.use_mt = CY_USE_MT,
+	.use_hndshk = CY_SEND_HNDSHK,
+	.use_trk_id = CY_USE_TRACKING_ID,
+	.use_sleep = CY_USE_DEEP_SLEEP_SEL | CY_USE_LOW_POWER_SEL,
+	.use_gestures = CY_USE_GESTURES,
+	.fw_fname = "cyttsp_8960_cdp.hex",
+	/* activate up to 4 groups
+	 * and set active distance
+	 */
+	.gest_set = CY_GEST_GRP1 | CY_GEST_GRP2 |
+				CY_GEST_GRP3 | CY_GEST_GRP4 |
+				CY_ACT_DIST,
+	/* change act_intrvl to customize the Active power state
+	 * scanning/processing refresh interval for Operating mode
+	 */
+	.act_intrvl = CY_ACT_INTRVL_DFLT,
+	/* change tch_tmout to customize the touch timeout for the
+	 * Active power state for Operating mode
+	 */
+	.tch_tmout = CY_TCH_TMOUT_DFLT,
+	/* change lp_intrvl to customize the Low Power power state
+	 * scanning/processing refresh interval for Operating mode
+	 */
+	.lp_intrvl = CY_LP_INTRVL_DFLT,
+	.sleep_gpio = CYTTSP_TS_SLEEP_GPIO,
+	.resout_gpio = CYTTSP_TS_RESOUT_N_GPIO,
+	.irq_gpio = CYTTSP_TS_GPIO_IRQ,
+	.regulator_info = regulator_data,
+	.num_regulators = ARRAY_SIZE(regulator_data),
+	.init = cyttsp_platform_init,
+	.correct_fw_ver = 9,
+};
+
+static struct i2c_board_info cyttsp_info[] __initdata = {
+	{
+		I2C_BOARD_INFO(CY_I2C_NAME, 0x24),
+		.platform_data = &cyttsp_pdata,
+#ifndef CY_USE_TIMER
+		.irq = MSM_GPIO_TO_INT(CYTTSP_TS_GPIO_IRQ),
+#endif /* CY_USE_TIMER */
+	},
+};
+
+/* configuration data */
+static const u8 mxt_config_data[] = {
+	/* T6 Object */
+	0, 0, 0, 0, 0, 0,
+	/* T38 Object */
+	11, 2, 0, 11, 11, 11, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0,
+	/* T7 Object */
+	100, 16, 50,
+	/* T8 Object */
+	8, 0, 0, 0, 0, 0, 8, 14, 50, 215,
+	/* T9 Object */
+	131, 0, 0, 26, 42, 0, 32, 63, 3, 5,
+	0, 2, 1, 113, 10, 10, 8, 10, 255, 2,
+	85, 5, 0, 0, 20, 20, 75, 25, 202, 29,
+	10, 10, 45, 46,
+	/* T15 Object */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0,
+	/* T22 Object */
+	5, 0, 0, 0, 0, 0, 0, 0, 30, 0,
+	0, 0, 5, 8, 10, 13, 0,
+	/* T24 Object */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* T25 Object */
+	3, 0, 188, 52, 52, 33, 0, 0, 0, 0,
+	0, 0, 0, 0,
+	/* T27 Object */
+	0, 0, 0, 0, 0, 0, 0,
+	/* T28 Object */
+	0, 0, 0, 8, 12, 60,
+	/* T40 Object */
+	0, 0, 0, 0, 0,
+	/* T41 Object */
+	0, 0, 0, 0, 0, 0,
+	/* T43 Object */
+	0, 0, 0, 0, 0, 0,
+};
+
+#define MXT_TS_GPIO_IRQ		11
+#define MXT_TS_LDO_EN_GPIO	50
+#define MXT_TS_RESET_GPIO	52
+
+static struct mxt_platform_data mxt_platform_data = {
+	.config			= mxt_config_data,
+	.config_length		= ARRAY_SIZE(mxt_config_data),
+	.x_size			= 1365,
+	.y_size			= 767,
+	.irqflags		= IRQF_TRIGGER_FALLING,
+	.i2c_pull_up		= true,
+};
+
+static struct i2c_board_info mxt_device_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("atmel_mxt_ts", 0x5b),
+		.platform_data = &mxt_platform_data,
+		.irq = MSM_GPIO_TO_INT(MXT_TS_GPIO_IRQ),
+	},
+};
+
+static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
+{
+}
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi4_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi3_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi10_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi12_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_rpm_platform_data msm_rpm_data = {
+	.reg_base_addrs = {
+		[MSM_RPM_PAGE_STATUS] = MSM_RPM_BASE,
+		[MSM_RPM_PAGE_CTRL] = MSM_RPM_BASE + 0x400,
+		[MSM_RPM_PAGE_REQ] = MSM_RPM_BASE + 0x600,
+		[MSM_RPM_PAGE_ACK] = MSM_RPM_BASE + 0xa00,
+	},
+
+	.irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
+	.irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
+	.irq_vmpm = RPM_APCC_CPU0_GP_MEDIUM_IRQ,
+	.msm_apps_ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
+	.msm_apps_ipc_rpm_val = 4,
+};
+
+static struct ks8851_pdata spi_eth_pdata = {
+	.irq_gpio = KS8851_IRQ_GPIO,
+	.rst_gpio = KS8851_RST_GPIO,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+	{
+		.modalias               = "ks8851",
+		.irq                    = MSM_GPIO_TO_INT(KS8851_IRQ_GPIO),
+		.max_speed_hz           = 19200000,
+		.bus_num                = 0,
+		.chip_select            = 0,
+		.mode                   = SPI_MODE_0,
+		.platform_data		= &spi_eth_pdata
+	},
+	{
+		.modalias               = "dsi_novatek_3d_panel_spi",
+		.max_speed_hz           = 10800000,
+		.bus_num                = 0,
+		.chip_select            = 1,
+		.mode                   = SPI_MODE_0,
+	},
+};
+
+static struct platform_device msm_device_saw_core0 = {
+	.name          = "saw-regulator",
+	.id            = 0,
+	.dev	= {
+		.platform_data = &msm_saw_regulator_pdata_s5,
+	},
+};
+
+static struct platform_device msm_device_saw_core1 = {
+	.name          = "saw-regulator",
+	.id            = 1,
+	.dev	= {
+		.platform_data = &msm_saw_regulator_pdata_s6,
+	},
+};
+
+static struct tsens_platform_data msm_tsens_pdata  = {
+		.slope			= 910,
+		.tsens_factor		= 1000,
+		.hw_type		= MSM_8960,
+		.tsens_num_sensor	= 5,
+};
+
+static struct platform_device msm_tsens_device = {
+	.name	= "tsens8960-tm",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &msm_tsens_pdata,
+	},
+};
+
+#ifdef CONFIG_MSM_FAKE_BATTERY
+static struct platform_device fish_battery_device = {
+	.name = "fish_battery",
+};
+#endif
+
+static struct platform_device msm8960_device_ext_5v_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= PM8921_MPP_PM_TO_SYS(7),
+	.dev	= {
+		.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
+	},
+};
+
+static struct platform_device msm8960_device_ext_l2_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= 91,
+	.dev	= {
+		.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_L2],
+	},
+};
+
+static struct platform_device msm8960_device_rpm_regulator __devinitdata = {
+	.name	= "rpm-regulator",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &msm_rpm_regulator_pdata,
+	},
+};
+
+static struct msm_rpm_log_platform_data msm_rpm_log_pdata = {
+	.phys_addr_base = 0x0010C000,
+	.reg_offsets = {
+		[MSM_RPM_LOG_PAGE_INDICES] = 0x00000080,
+		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
+	},
+	.phys_size = SZ_8K,
+	.log_len = 4096,		  /* log's buffer length in bytes */
+	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+};
+
+static struct platform_device msm_rpm_log_device = {
+	.name	= "msm_rpm_log",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &msm_rpm_log_pdata,
+	},
+};
+
+static struct platform_device *common_devices[] __initdata = {
+	&msm8960_device_dmov,
+	&msm_device_smd,
+	&msm8960_device_uart_gsbi5,
+	&msm_device_uart_dm6,
+	&msm_device_saw_core0,
+	&msm_device_saw_core1,
+	&msm8960_device_ext_5v_vreg,
+	&msm8960_device_ext_l2_vreg,
+	&msm8960_device_ssbi_pm8921,
+	&msm8960_device_qup_spi_gsbi1,
+	&msm8960_device_qup_i2c_gsbi3,
+	&msm8960_device_qup_i2c_gsbi4,
+	&msm8960_device_qup_i2c_gsbi10,
+	&msm8960_device_qup_i2c_gsbi12,
+	&msm_slim_ctrl,
+	&msm_device_wcnss_wlan,
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+	&qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+	&qcedev_device,
+#endif
+#ifdef CONFIG_MSM_ROTATOR
+	&msm_rotator_device,
+#endif
+	&msm_device_sps,
+#ifdef CONFIG_MSM_FAKE_BATTERY
+	&fish_battery_device,
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	&android_pmem_device,
+	&android_pmem_adsp_device,
+#endif
+	&android_pmem_audio_device,
+#endif
+	&msm_device_vidc,
+	&msm_device_bam_dmux,
+	&msm_fm_platform_init,
+
+#ifdef CONFIG_HW_RANDOM_MSM
+	&msm_device_rng,
+#endif
+	&msm_rpm_device,
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
+	&msm_rpm_log_device,
+	&msm_rpm_stat_device,
+	&msm_device_tz_log,
+
+#ifdef CONFIG_MSM_QDSS
+	&msm_etb_device,
+	&msm_tpiu_device,
+	&msm_funnel_device,
+	&msm_debug_device,
+	&msm_ptm_device,
+#endif
+	&msm_device_dspcrashd_8960,
+	&msm8960_device_watchdog,
+};
+
+static struct platform_device *cdp_devices[] __initdata = {
+	&msm8960_device_otg,
+	&msm8960_device_gadget_peripheral,
+	&msm_device_hsusb_host,
+	&android_usb_device,
+	&msm_pcm,
+	&msm_pcm_routing,
+	&msm_cpudai0,
+	&msm_cpudai1,
+	&msm_cpudai_hdmi_rx,
+	&msm_cpudai_bt_rx,
+	&msm_cpudai_bt_tx,
+	&msm_cpudai_fm_rx,
+	&msm_cpudai_fm_tx,
+	&msm_cpudai_auxpcm_rx,
+	&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
+	&msm_voice,
+	&msm_voip,
+	&msm_lpa_pcm,
+	&msm_cpudai_afe_01_rx,
+	&msm_cpudai_afe_01_tx,
+	&msm_cpudai_afe_02_rx,
+	&msm_cpudai_afe_02_tx,
+	&msm_pcm_afe,
+	&msm_pcm_hostless,
+	&msm_bus_apps_fabric,
+	&msm_bus_sys_fabric,
+	&msm_bus_mm_fabric,
+	&msm_bus_sys_fpb,
+	&msm_bus_cpss_fpb,
+	&msm_tsens_device,
+};
+
+static void __init msm8930_i2c_init(void)
+{
+	msm8960_device_qup_i2c_gsbi4.dev.platform_data =
+					&msm8960_i2c_qup_gsbi4_pdata;
+
+	msm8960_device_qup_i2c_gsbi3.dev.platform_data =
+					&msm8960_i2c_qup_gsbi3_pdata;
+
+	msm8960_device_qup_i2c_gsbi10.dev.platform_data =
+					&msm8960_i2c_qup_gsbi10_pdata;
+
+	msm8960_device_qup_i2c_gsbi12.dev.platform_data =
+					&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},
+
+	{0, 1, "C1", "STANDALONE_POWER_COLLAPSE",
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
+
+	{0, 2, "C2", "POWER_COLLAPSE",
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE},
+
+	{1, 0, "C0", "WFI",
+		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
+
+	{1, 1, "C1", "STANDALONE_POWER_COLLAPSE",
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
+};
+
+static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR * 2] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 1,
+		.suspend_enabled = 1,
+	},
+
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
+		.idle_supported = 0,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+		.idle_supported = 1,
+		.suspend_supported = 0,
+		.idle_enabled = 1,
+		.suspend_enabled = 0,
+	},
+};
+
+static struct msm_rpmrs_level msm_rpmrs_levels[] __initdata = {
+	{
+		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT,
+		MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
+		true,
+		100, 8000, 100000, 1,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
+		MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
+		true,
+		2000, 6000, 60100000, 3000,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(ON, GDHS, MAX, ACTIVE),
+		false,
+		4200, 5000, 60350000, 3500,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(ON, HSFS_OPEN, MAX, ACTIVE),
+		false,
+		6300, 4500, 65350000, 4800,
+	},
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(ON, HSFS_OPEN, ACTIVE, RET_HIGH),
+		false,
+		7000, 3500, 66600000, 5150,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, GDHS, MAX, ACTIVE),
+		false,
+		11700, 2500, 67850000, 5500,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, MAX, ACTIVE),
+		false,
+		13800, 2000, 71850000, 6800,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, ACTIVE, RET_HIGH),
+		false,
+		29700, 500, 75850000, 8800,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, RET_HIGH, RET_LOW),
+		false,
+		29700, 0, 76350000, 9800,
+	},
+};
+
+#ifdef CONFIG_I2C
+#define I2C_SURF 1
+#define I2C_FFA  (1 << 1)
+#define I2C_RUMI (1 << 2)
+#define I2C_SIM  (1 << 3)
+#define I2C_FLUID (1 << 4)
+#define I2C_LIQUID (1 << 5)
+
+struct i2c_registry {
+	u8                     machs;
+	int                    bus;
+	struct i2c_board_info *info;
+	int                    len;
+};
+
+#ifdef CONFIG_MSM_CAMERA
+static struct i2c_board_info msm_camera_boardinfo[] __initdata = {
+#ifdef CONFIG_IMX074
+	{
+	I2C_BOARD_INFO("imx074", 0x1A),
+	},
+#endif
+#ifdef CONFIG_OV2720
+	{
+	I2C_BOARD_INFO("ov2720", 0x6C),
+	},
+#endif
+#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
+	{
+	I2C_BOARD_INFO("sc628a", 0x6E),
+	},
+#endif
+};
+#endif
+
+static void __init msm8930_init_hsic(void)
+{
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+	uint32_t version = socinfo_get_version();
+
+	pr_info("%s: version:%d mtp:%d\n", __func__,
+			SOCINFO_VERSION_MAJOR(version),
+			machine_is_msm8930_mtp());
+
+	if ((SOCINFO_VERSION_MAJOR(version) == 1) ||
+			machine_is_msm8930_mtp() ||
+			machine_is_msm8930_fluid())
+		return;
+
+	platform_device_register(&msm_device_hsic_host);
+#endif
+}
+
+#ifdef CONFIG_ISL9519_CHARGER
+static struct isl_platform_data isl_data __initdata = {
+	.valid_n_gpio		= 0,	/* Not required when notify-by-pmic */
+	.chg_detection_config	= NULL,	/* Not required when notify-by-pmic */
+	.max_system_voltage	= 4200,
+	.min_system_voltage	= 3200,
+	.chgcurrent		= 1000, /* 1900, */
+	.term_current		= 400,	/* Need fine tuning */
+	.input_current		= 2048,
+};
+
+static struct i2c_board_info isl_charger_i2c_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("isl9519q", 0x9),
+		.irq		= 0,	/* Not required when notify-by-pmic */
+		.platform_data	= &isl_data,
+	},
+};
+#endif /* CONFIG_ISL9519_CHARGER */
+
+static struct i2c_registry msm8960_i2c_devices[] __initdata = {
+#ifdef CONFIG_MSM_CAMERA
+	{
+		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI,
+		MSM_8930_GSBI4_QUP_I2C_BUS_ID,
+		msm_camera_boardinfo,
+		ARRAY_SIZE(msm_camera_boardinfo),
+	},
+#endif
+#ifdef CONFIG_ISL9519_CHARGER
+	{
+		I2C_LIQUID,
+		MSM_8930_GSBI10_QUP_I2C_BUS_ID,
+		isl_charger_i2c_info,
+		ARRAY_SIZE(isl_charger_i2c_info),
+	},
+#endif /* CONFIG_ISL9519_CHARGER */
+	{
+		I2C_SURF | I2C_FFA | I2C_FLUID,
+		MSM_8930_GSBI3_QUP_I2C_BUS_ID,
+		cyttsp_info,
+		ARRAY_SIZE(cyttsp_info),
+	},
+	{
+		I2C_LIQUID,
+		MSM_8930_GSBI3_QUP_I2C_BUS_ID,
+		mxt_device_info,
+		ARRAY_SIZE(mxt_device_info),
+	},
+	{
+		I2C_LIQUID,
+		MSM_8930_GSBI10_QUP_I2C_BUS_ID,
+		msm_isa1200_board_info,
+		ARRAY_SIZE(msm_isa1200_board_info),
+	},
+};
+#endif /* CONFIG_I2C */
+
+static void __init register_i2c_devices(void)
+{
+#ifdef CONFIG_I2C
+	u8 mach_mask = 0;
+	int i;
+
+	/* Build the matching 'supported_machs' bitmask */
+	if (machine_is_msm8930_cdp() || machine_is_msm8627_cdp())
+		mach_mask = I2C_SURF;
+	else if (machine_is_msm8930_fluid())
+		mach_mask = I2C_FLUID;
+	else if (machine_is_msm8930_mtp() || machine_is_msm8627_mtp())
+		mach_mask = I2C_FFA;
+	else
+		pr_err("unmatched machine ID in register_i2c_devices\n");
+
+	/* Run the array and install devices as appropriate */
+	for (i = 0; i < ARRAY_SIZE(msm8960_i2c_devices); ++i) {
+		if (msm8960_i2c_devices[i].machs & mach_mask)
+			i2c_register_board_info(msm8960_i2c_devices[i].bus,
+						msm8960_i2c_devices[i].info,
+						msm8960_i2c_devices[i].len);
+	}
+#endif
+}
+
+static void __init msm8930_cdp_init(void)
+{
+	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
+		pr_err("meminfo_init() failed!\n");
+
+	BUG_ON(msm_rpm_init(&msm_rpm_data));
+	BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
+				ARRAY_SIZE(msm_rpmrs_levels)));
+
+	regulator_suppress_info_printing();
+	if (msm_xo_init())
+		pr_err("Failed to initialize XO votes\n");
+	platform_device_register(&msm8960_device_rpm_regulator);
+	msm_clock_init(&msm8960_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();
+	msm8960_device_qup_spi_gsbi1.dev.platform_data =
+				&msm8960_qup_spi_gsbi1_pdata;
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+	msm8930_init_pmic();
+	msm8930_i2c_init();
+	msm8930_gfx_init();
+	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_pm8921_gpio_mpp_init();
+	platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
+	msm8930_init_hsic();
+	msm8930_init_cam();
+	msm8930_init_mmc();
+	acpuclk_init(&acpuclk_8960_soc_data);
+	register_i2c_devices();
+	msm8930_init_fb();
+	slim_register_board_info(msm_slim_devices,
+		ARRAY_SIZE(msm_slim_devices));
+	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
+	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
+	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
+				msm_pm_data);
+	change_memory_power = &msm8930_change_memory_power;
+	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
+
+	if (PLATFORM_IS_CHARM25())
+		platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
+}
+
+MACHINE_START(MSM8930_CDP, "QCT MSM8930 CDP")
+	.map_io = msm8930_map_io,
+	.reserve = msm8930_reserve,
+	.init_irq = msm8930_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8930_cdp_init,
+	.init_early = msm8930_allocate_memory_regions,
+	.init_very_early = msm8930_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8930_MTP, "QCT MSM8930 MTP")
+	.map_io = msm8930_map_io,
+	.reserve = msm8930_reserve,
+	.init_irq = msm8930_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8930_cdp_init,
+	.init_early = msm8930_allocate_memory_regions,
+	.init_very_early = msm8930_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8930_FLUID, "QCT MSM8930 FLUID")
+	.map_io = msm8930_map_io,
+	.reserve = msm8930_reserve,
+	.init_irq = msm8930_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8930_cdp_init,
+	.init_early = msm8930_allocate_memory_regions,
+	.init_very_early = msm8930_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8627_CDP, "QCT MSM8627 CDP")
+	.map_io = msm8930_map_io,
+	.reserve = msm8930_reserve,
+	.init_irq = msm8930_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8930_cdp_init,
+	.init_early = msm8930_allocate_memory_regions,
+	.init_very_early = msm8930_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8627_MTP, "QCT MSM8627 MTP")
+	.map_io = msm8930_map_io,
+	.reserve = msm8930_reserve,
+	.init_irq = msm8930_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8930_cdp_init,
+	.init_early = msm8930_allocate_memory_regions,
+	.init_very_early = msm8930_early_memory,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
new file mode 100644
index 0000000..c413061
--- /dev/null
+++ b/arch/arm/mach-msm/board-8930.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2011, 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 __ARCH_ARM_MACH_MSM_BOARD_MSM8930_H
+#define __ARCH_ARM_MACH_MSM_BOARD_MSM8930_H
+
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/i2c/sx150x.h>
+#include <mach/irqs.h>
+#include <mach/rpm-regulator.h>
+
+/* Macros assume PMIC GPIOs and MPPs start at 1 */
+#define PM8921_GPIO_BASE		NR_GPIO_IRQS
+#define PM8921_GPIO_PM_TO_SYS(pm_gpio)	(pm_gpio - 1 + PM8921_GPIO_BASE)
+#define PM8921_MPP_BASE			(PM8921_GPIO_BASE + PM8921_NR_GPIOS)
+#define PM8921_MPP_PM_TO_SYS(pm_gpio)	(pm_gpio - 1 + PM8921_MPP_BASE)
+#define PM8921_IRQ_BASE			(NR_MSM_IRQS + NR_GPIO_IRQS)
+
+extern struct pm8921_regulator_platform_data
+	msm_pm8921_regulator_pdata[] __devinitdata;
+
+extern int msm_pm8921_regulator_pdata_len __devinitdata;
+
+#define GPIO_VREG_ID_EXT_5V		0
+#define GPIO_VREG_ID_EXT_L2		1
+#define GPIO_VREG_ID_EXT_3P3V		2
+
+extern struct gpio_regulator_platform_data
+	msm_gpio_regulator_pdata[] __devinitdata;
+
+extern struct regulator_init_data msm_saw_regulator_pdata_s5;
+extern struct regulator_init_data msm_saw_regulator_pdata_s6;
+
+extern struct rpm_regulator_platform_data msm_rpm_regulator_pdata __devinitdata;
+
+#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
+enum {
+	GPIO_EXPANDER_IRQ_BASE = (PM8921_IRQ_BASE + PM8921_NR_IRQS),
+	GPIO_EXPANDER_GPIO_BASE = (PM8921_MPP_BASE + PM8921_NR_MPPS),
+	/* CAM Expander */
+	GPIO_CAM_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
+	GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
+	GPIO_CAM_GP_AFBUSY,
+	GPIO_CAM_GP_STROBE_CE,
+	GPIO_CAM_GP_CAM1MP_XCLR,
+	GPIO_CAM_GP_CAMIF_RESET_N,
+	GPIO_CAM_GP_XMT_FLASH_INT,
+	GPIO_CAM_GP_LED_EN1,
+	GPIO_CAM_GP_LED_EN2,
+
+};
+#endif
+
+enum {
+	SX150X_CAM,
+};
+
+#endif
+
+extern struct sx150x_platform_data msm8930_sx150x_data[];
+void msm8930_init_cam(void);
+void msm8930_init_fb(void);
+void msm8930_init_pmic(void);
+void msm8930_init_mmc(void);
+int msm8930_init_gpiomux(void);
+void msm8930_allocate_fb_region(void);
+void msm8930_pm8921_gpio_mpp_init(void);
+
+#define PLATFORM_IS_CHARM25() \
+	(machine_is_msm8930_cdp() && \
+		(socinfo_get_platform_subtype() == 1) \
+	)
+
+#define MSM_8930_GSBI4_QUP_I2C_BUS_ID 4
+#define MSM_8930_GSBI3_QUP_I2C_BUS_ID 3
+#define MSM_8930_GSBI10_QUP_I2C_BUS_ID 10
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
new file mode 100644
index 0000000..e827b2b
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -0,0 +1,503 @@
+/* Copyright (c) 2011, 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/i2c.h>
+#include <linux/i2c/sx150x.h>
+#include <asm/mach-types.h>
+#include <mach/board.h>
+#include <mach/msm_bus_board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8960.h"
+
+#if (defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)) && \
+	defined(CONFIG_I2C)
+
+static struct i2c_board_info cam_expander_i2c_info[] = {
+	{
+		I2C_BOARD_INFO("sx1508q", 0x22),
+		.platform_data = &msm8960_sx150x_data[SX150X_CAM]
+	},
+};
+
+static struct msm_cam_expander_info cam_expander_info[] = {
+	{
+		cam_expander_i2c_info,
+		MSM_8960_GSBI4_QUP_I2C_BUS_ID,
+	},
+};
+#endif
+
+static struct gpiomux_setting cam_settings[] = {
+	{
+		.func = GPIOMUX_FUNC_GPIO, /*suspend*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_DOWN,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_1, /*active 1*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_GPIO, /*active 2*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_1, /*active 3*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_5, /*active 4*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_6, /*active 5*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_2, /*active 6*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_3, /*active 7*/
+		.drv = GPIOMUX_DRV_8MA,
+		.pull = GPIOMUX_PULL_UP,
+	},
+
+	{
+		.func = GPIOMUX_FUNC_GPIO, /*i2c suspend*/
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_KEEPER,
+	},
+
+};
+
+static struct msm_gpiomux_config msm8960_cdp_flash_configs[] = {
+	{
+		.gpio = 3,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
+	{
+		.gpio = 2,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 3,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 4,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 5,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[1],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 76,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+	{
+		.gpio = 107,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[2],
+			[GPIOMUX_SUSPENDED] = &cam_settings[0],
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
+	{
+		.gpio = 18,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 19,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 20,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+	{
+		.gpio = 21,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cam_settings[3],
+			[GPIOMUX_SUSPENDED] = &cam_settings[8],
+		},
+	},
+};
+
+#ifdef CONFIG_MSM_CAMERA
+
+static uint16_t msm_cam_gpio_2d_tbl[] = {
+	5, /*CAMIF_MCLK*/
+	20, /*CAMIF_I2C_DATA*/
+	21, /*CAMIF_I2C_CLK*/
+};
+
+static struct msm_camera_gpio_conf gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
+	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
+};
+
+#define VFE_CAMIF_TIMER1_GPIO 2
+#define VFE_CAMIF_TIMER2_GPIO 3
+#define VFE_CAMIF_TIMER3_GPIO_INT 4
+static struct msm_camera_sensor_strobe_flash_data strobe_flash_xenon = {
+	.flash_trigger = VFE_CAMIF_TIMER2_GPIO,
+	.flash_charge = VFE_CAMIF_TIMER1_GPIO,
+	.flash_charge_done = VFE_CAMIF_TIMER3_GPIO_INT,
+	.flash_recharge_duration = 50000,
+	.irq = MSM_GPIO_TO_INT(VFE_CAMIF_TIMER3_GPIO_INT),
+};
+
+#ifdef CONFIG_MSM_CAMERA_FLASH
+static struct msm_camera_sensor_flash_src msm_flash_src = {
+	.flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
+	._fsrc.ext_driver_src.led_en = VFE_CAMIF_TIMER1_GPIO,
+	._fsrc.ext_driver_src.led_flash_en = VFE_CAMIF_TIMER2_GPIO,
+};
+#endif
+
+static struct msm_bus_vectors cam_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_preview_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 27648000,
+		.ib  = 110592000,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_video_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 140451840,
+		.ib  = 561807360,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 206807040,
+		.ib  = 488816640,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+};
+
+static struct msm_bus_vectors cam_snapshot_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 274423680,
+		.ib  = 1097694720,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 540000000,
+		.ib  = 1350000000,
+	},
+};
+
+static struct msm_bus_vectors cam_zsl_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VFE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 302071680,
+		.ib  = 1208286720,
+	},
+	{
+		.src = MSM_BUS_MASTER_VPE,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_JPEG_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 540000000,
+		.ib  = 1350000000,
+	},
+};
+
+static struct msm_bus_paths cam_bus_client_config[] = {
+	{
+		ARRAY_SIZE(cam_init_vectors),
+		cam_init_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_preview_vectors),
+		cam_preview_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_video_vectors),
+		cam_video_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_snapshot_vectors),
+		cam_snapshot_vectors,
+	},
+	{
+		ARRAY_SIZE(cam_zsl_vectors),
+		cam_zsl_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata cam_bus_client_pdata = {
+		cam_bus_client_config,
+		ARRAY_SIZE(cam_bus_client_config),
+		.name = "msm_camera",
+};
+
+static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
+	{
+		.ioclk.mclk_clk_rate = 24000000,
+		.ioclk.vfe_clk_rate  = 228570000,
+		.csid_core = 0,
+		.cam_bus_scale_table = &cam_bus_client_pdata,
+	},
+	{
+		.ioclk.mclk_clk_rate = 24000000,
+		.ioclk.vfe_clk_rate  = 228570000,
+		.csid_core = 1,
+		.cam_bus_scale_table = &cam_bus_client_pdata,
+	},
+};
+
+#ifdef CONFIG_IMX074_ACT
+static struct i2c_board_info imx074_actuator_i2c_info = {
+	I2C_BOARD_INFO("imx074_act", 0x11),
+};
+
+static struct msm_actuator_info imx074_actuator_info = {
+	.board_info     = &imx074_actuator_i2c_info,
+	.bus_id         = MSM_8960_GSBI4_QUP_I2C_BUS_ID,
+	.vcm_pwd        = 0,
+	.vcm_enable     = 1,
+};
+#endif
+
+#ifdef CONFIG_IMX074
+static struct msm_camera_sensor_flash_data flash_imx074 = {
+	.flash_type	= MSM_CAMERA_FLASH_LED,
+#ifdef CONFIG_MSM_CAMERA_FLASH
+	.flash_src	= &msm_flash_src
+#endif
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
+	.mount_angle	= 90,
+	.sensor_reset	= 107,
+	.sensor_pwd	= 85,
+	.vcm_pwd	= 0,
+	.vcm_enable	= 1,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
+	.sensor_name	= "imx074",
+	.pdata	= &msm_camera_csi_device_data[0],
+	.flash_data	= &flash_imx074,
+	.strobe_flash_data = &strobe_flash_xenon,
+	.sensor_platform_info = &sensor_board_info_imx074,
+	.gpio_conf = &gpio_conf,
+	.csi_if	= 1,
+	.camera_type = BACK_CAMERA_2D,
+#ifdef CONFIG_IMX074_ACT
+	.actuator_info = &imx074_actuator_info
+#endif
+};
+
+static struct platform_device msm8960_camera_sensor_imx074 = {
+	.name	= "msm_camera_imx074",
+	.dev	= {
+		.platform_data = &msm_camera_sensor_imx074_data,
+	},
+};
+#endif
+#ifdef CONFIG_OV2720
+static struct msm_camera_sensor_flash_data flash_ov2720 = {
+	.flash_type	= MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
+	.mount_angle	= 0,
+	.sensor_reset	= 76,
+	.sensor_pwd	= 85,
+	.vcm_pwd	= 0,
+	.vcm_enable	= 1,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
+	.sensor_name	= "ov2720",
+	.pdata	= &msm_camera_csi_device_data[1],
+	.flash_data	= &flash_ov2720,
+	.sensor_platform_info = &sensor_board_info_ov2720,
+	.gpio_conf = &gpio_conf,
+	.csi_if	= 1,
+	.camera_type = FRONT_CAMERA_2D,
+};
+
+static struct platform_device msm8960_camera_sensor_ov2720 = {
+	.name	= "msm_camera_ov2720",
+	.dev	= {
+		.platform_data = &msm_camera_sensor_ov2720_data,
+	},
+};
+#endif
+
+static struct msm8960_privacy_light_cfg privacy_light_info = {
+	.mpp = PM8921_MPP_PM_TO_SYS(12),
+};
+
+void __init msm8960_init_cam(void)
+{
+	int i;
+	struct platform_device *cam_dev[] = {
+		&msm8960_camera_sensor_imx074,
+		&msm8960_camera_sensor_ov2720,
+	};
+
+	msm_gpiomux_install(msm8960_cam_common_configs,
+			ARRAY_SIZE(msm8960_cam_common_configs));
+
+	if (machine_is_msm8960_cdp()) {
+		msm_gpiomux_install(msm8960_cdp_flash_configs,
+			ARRAY_SIZE(msm8960_cdp_flash_configs));
+		msm_flash_src._fsrc.ext_driver_src.led_en =
+			GPIO_CAM_GP_LED_EN1;
+		msm_flash_src._fsrc.ext_driver_src.led_flash_en =
+			GPIO_CAM_GP_LED_EN2;
+		#if defined(CONFIG_I2C) && (defined(CONFIG_GPIO_SX150X) || \
+		defined(CONFIG_GPIO_SX150X_MODULE))
+		msm_flash_src._fsrc.ext_driver_src.expander_info =
+			cam_expander_info;
+		#endif
+	}
+
+	if (machine_is_msm8960_liquid()) {
+		struct msm_camera_sensor_info *s_info;
+		s_info = msm8960_camera_sensor_imx074.dev.platform_data;
+		s_info->sensor_platform_info->mount_angle = 180;
+		s_info = msm8960_camera_sensor_ov2720.dev.platform_data;
+		s_info->sensor_platform_info->privacy_light = 1;
+		s_info->sensor_platform_info->privacy_light_info =
+			&privacy_light_info;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cam_dev); i++) {
+		struct msm_camera_sensor_info *s_info;
+		s_info = cam_dev[i]->dev.platform_data;
+		msm_get_cam_resources(s_info);
+		platform_device_register(cam_dev[i]);
+	}
+
+	platform_device_register(&msm8960_device_csiphy0);
+	platform_device_register(&msm8960_device_csiphy1);
+	platform_device_register(&msm8960_device_csid0);
+	platform_device_register(&msm8960_device_csid1);
+	platform_device_register(&msm8960_device_ispif);
+	platform_device_register(&msm8960_device_vfe);
+	platform_device_register(&msm8960_device_vpe);
+}
+#endif
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
new file mode 100644
index 0000000..63c51ea
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -0,0 +1,961 @@
+/* Copyright (c) 2011, 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/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <asm/mach-types.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8960.h"
+
+#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
+#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 3) /* 4 bpp x 3 pages */
+#else
+#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 2) /* 4 bpp x 2 pages */
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+#define MSM_FB_EXT_BUF_SIZE	(1920 * 1088 * 2 * 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 */
+#else
+#define MSM_FB_EXT_BUF_SIZE	0
+#endif
+
+#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
+/* width x height x 3 bpp x 2 frame buffer */
+#define MSM_FB_WRITEBACK_SIZE (1376 * 768 * 3 * 2)
+#define MSM_FB_WRITEBACK_OFFSET  \
+		(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE)
+#else
+#define MSM_FB_WRITEBACK_SIZE   0
+#define MSM_FB_WRITEBACK_OFFSET 0
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+/* 4 bpp x 2 page HDMI case */
+#define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
+#else
+/* Note: must be multiple of 4096 */
+#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
+				MSM_FB_WRITEBACK_SIZE, 4096)
+#endif
+
+#define MDP_VSYNC_GPIO 0
+
+#define PANEL_NAME_MAX_LEN	30
+#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME	"mipi_cmd_novatek_qhd"
+#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME	"mipi_video_novatek_qhd"
+#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME	"mipi_video_toshiba_wsvga"
+#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME	"mipi_video_chimei_wxga"
+#define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME	"mipi_video_simulator_vga"
+#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME	"mipi_cmd_renesas_fwvga"
+#define HDMI_PANEL_NAME	"hdmi_msm"
+#define TVOUT_PANEL_NAME	"tvout_msm"
+
+static int writeback_offset(void)
+{
+	return MSM_FB_WRITEBACK_OFFSET;
+}
+
+static struct resource msm_fb_resources[] = {
+	{
+		.flags = IORESOURCE_DMA,
+	}
+};
+
+static int msm_fb_detect_panel(const char *name)
+{
+	if (machine_is_msm8960_liquid()) {
+		if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
+				strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
+					PANEL_NAME_MAX_LEN)))
+			return 0;
+	} else {
+		if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
+				strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
+					PANEL_NAME_MAX_LEN)))
+			return 0;
+
+#ifndef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+		if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+				strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
+					PANEL_NAME_MAX_LEN)))
+			return 0;
+
+		if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+				strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
+					PANEL_NAME_MAX_LEN)))
+			return 0;
+
+		if (!strncmp(name, MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
+				strnlen(MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
+					PANEL_NAME_MAX_LEN)))
+			return 0;
+
+		if (!strncmp(name, MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+				strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
+					PANEL_NAME_MAX_LEN)))
+			return 0;
+#endif
+	}
+
+	if (!strncmp(name, HDMI_PANEL_NAME,
+			strnlen(HDMI_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+	if (!strncmp(name, TVOUT_PANEL_NAME,
+			strnlen(TVOUT_PANEL_NAME,
+				PANEL_NAME_MAX_LEN)))
+		return 0;
+
+	pr_warning("%s: not supported '%s'", __func__, name);
+	return -ENODEV;
+}
+
+static struct msm_fb_platform_data msm_fb_pdata = {
+	.detect_client = msm_fb_detect_panel,
+};
+
+static struct platform_device msm_fb_device = {
+	.name   = "msm_fb",
+	.id     = 0,
+	.num_resources     = ARRAY_SIZE(msm_fb_resources),
+	.resource          = msm_fb_resources,
+	.dev.platform_data = &msm_fb_pdata,
+};
+
+static bool dsi_power_on;
+
+/**
+ * LiQUID panel on/off
+ *
+ * @param on
+ *
+ * @return int
+ */
+static int mipi_dsi_liquid_panel_power(int on)
+{
+	static struct regulator *reg_l2, *reg_ext_3p3v;
+	static int gpio21, gpio24, gpio43;
+	int rc;
+
+	pr_info("%s: on=%d\n", __func__, on);
+
+	gpio21 = PM8921_GPIO_PM_TO_SYS(21); /* disp power enable_n */
+	gpio43 = PM8921_GPIO_PM_TO_SYS(43); /* Displays Enable (rst_n)*/
+	gpio24 = PM8921_GPIO_PM_TO_SYS(24); /* Backlight PWM */
+
+	if (!dsi_power_on) {
+
+		reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
+				"dsi_vdda");
+		if (IS_ERR(reg_l2)) {
+			pr_err("could not get 8921_l2, rc = %ld\n",
+				PTR_ERR(reg_l2));
+			return -ENODEV;
+		}
+
+		rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
+		if (rc) {
+			pr_err("set_voltage l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+
+		reg_ext_3p3v = regulator_get(&msm_mipi_dsi1_device.dev,
+			"vdd_lvds_3p3v");
+		if (IS_ERR(reg_ext_3p3v)) {
+			pr_err("could not get reg_ext_3p3v, rc = %ld\n",
+			       PTR_ERR(reg_ext_3p3v));
+		    return -ENODEV;
+		}
+
+		rc = gpio_request(gpio21, "disp_pwr_en_n");
+		if (rc) {
+			pr_err("request gpio 21 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+
+		rc = gpio_request(gpio43, "disp_rst_n");
+		if (rc) {
+			pr_err("request gpio 43 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+
+		rc = gpio_request(gpio24, "disp_backlight_pwm");
+		if (rc) {
+			pr_err("request gpio 24 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+
+		dsi_power_on = true;
+	}
+
+	if (on) {
+		rc = regulator_set_optimum_mode(reg_l2, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_enable(reg_l2);
+		if (rc) {
+			pr_err("enable l2 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+
+		rc = regulator_enable(reg_ext_3p3v);
+		if (rc) {
+			pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+
+		/* set reset pin before power enable */
+		gpio_set_value_cansleep(gpio43, 0); /* disp disable (resx=0) */
+
+		gpio_set_value_cansleep(gpio21, 0); /* disp power enable_n */
+		msleep(20);
+		gpio_set_value_cansleep(gpio43, 1); /* disp enable */
+		msleep(20);
+		gpio_set_value_cansleep(gpio43, 0); /* disp enable */
+		msleep(20);
+		gpio_set_value_cansleep(gpio43, 1); /* disp enable */
+		msleep(20);
+	} else {
+		gpio_set_value_cansleep(gpio43, 0);
+		gpio_set_value_cansleep(gpio21, 1);
+
+		rc = regulator_disable(reg_l2);
+		if (rc) {
+			pr_err("disable reg_l2 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_disable(reg_ext_3p3v);
+		if (rc) {
+			pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_set_optimum_mode(reg_l2, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int mipi_dsi_cdp_panel_power(int on)
+{
+	static struct regulator *reg_l8, *reg_l23, *reg_l2;
+	static int gpio43;
+	int rc;
+
+	pr_info("%s: state : %d\n", __func__, on);
+
+	if (!dsi_power_on) {
+
+		reg_l8 = regulator_get(&msm_mipi_dsi1_device.dev,
+				"dsi_vdc");
+		if (IS_ERR(reg_l8)) {
+			pr_err("could not get 8921_l8, rc = %ld\n",
+				PTR_ERR(reg_l8));
+			return -ENODEV;
+		}
+		reg_l23 = regulator_get(&msm_mipi_dsi1_device.dev,
+				"dsi_vddio");
+		if (IS_ERR(reg_l23)) {
+			pr_err("could not get 8921_l23, rc = %ld\n",
+				PTR_ERR(reg_l23));
+			return -ENODEV;
+		}
+		reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
+				"dsi_vdda");
+		if (IS_ERR(reg_l2)) {
+			pr_err("could not get 8921_l2, rc = %ld\n",
+				PTR_ERR(reg_l2));
+			return -ENODEV;
+		}
+		rc = regulator_set_voltage(reg_l8, 2800000, 3000000);
+		if (rc) {
+			pr_err("set_voltage l8 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_voltage(reg_l23, 1800000, 1800000);
+		if (rc) {
+			pr_err("set_voltage l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
+		if (rc) {
+			pr_err("set_voltage l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		gpio43 = PM8921_GPIO_PM_TO_SYS(43);
+		rc = gpio_request(gpio43, "disp_rst_n");
+		if (rc) {
+			pr_err("request gpio 43 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		dsi_power_on = true;
+	}
+	if (on) {
+		rc = regulator_set_optimum_mode(reg_l8, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l23, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l2, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_enable(reg_l8);
+		if (rc) {
+			pr_err("enable l8 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_enable(reg_l23);
+		if (rc) {
+			pr_err("enable l8 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_enable(reg_l2);
+		if (rc) {
+			pr_err("enable l2 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		gpio_set_value_cansleep(gpio43, 1);
+	} else {
+		rc = regulator_disable(reg_l2);
+		if (rc) {
+			pr_err("disable reg_l2 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_disable(reg_l8);
+		if (rc) {
+			pr_err("disable reg_l8 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_disable(reg_l23);
+		if (rc) {
+			pr_err("disable reg_l23 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_set_optimum_mode(reg_l8, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l23, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_set_optimum_mode(reg_l2, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		gpio_set_value_cansleep(gpio43, 0);
+	}
+	return 0;
+}
+
+static int mipi_dsi_panel_power(int on)
+{
+	int ret;
+
+	pr_info("%s: on=%d\n", __func__, on);
+
+	if (machine_is_msm8960_liquid())
+		ret = mipi_dsi_liquid_panel_power(on);
+	else
+		ret = mipi_dsi_cdp_panel_power(on);
+
+	return ret;
+}
+
+static struct mipi_dsi_platform_data mipi_dsi_pdata = {
+	.vsync_gpio = MDP_VSYNC_GPIO,
+	.dsi_power_save = mipi_dsi_panel_power,
+};
+
+#ifdef CONFIG_MSM_BUS_SCALING
+
+static struct msm_bus_vectors mdp_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+static struct msm_bus_vectors hdmi_as_primary_vectors[] = {
+	/* If HDMI is used as primary */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 2000000000,
+		.ib = 2000000000,
+	},
+};
+static struct msm_bus_paths mdp_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(mdp_init_vectors),
+		mdp_init_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+	{
+		ARRAY_SIZE(hdmi_as_primary_vectors),
+		hdmi_as_primary_vectors,
+	},
+};
+#else
+static struct msm_bus_vectors mdp_ui_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 216000000 * 2,
+		.ib = 270000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_vga_vectors[] = {
+	/* VGA and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 216000000 * 2,
+		.ib = 270000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_720p_vectors[] = {
+	/* 720p and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 230400000 * 2,
+		.ib = 288000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_1080p_vectors[] = {
+	/* 1080p and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 334080000 * 2,
+		.ib = 417600000 * 2,
+	},
+};
+
+static struct msm_bus_paths mdp_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(mdp_init_vectors),
+		mdp_init_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_ui_vectors),
+		mdp_ui_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_ui_vectors),
+		mdp_ui_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_vga_vectors),
+		mdp_vga_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_720p_vectors),
+		mdp_720p_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_1080p_vectors),
+		mdp_1080p_vectors,
+	},
+};
+#endif
+
+static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
+	mdp_bus_scale_usecases,
+	ARRAY_SIZE(mdp_bus_scale_usecases),
+	.name = "mdp",
+};
+
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+static int mdp_core_clk_rate_table[] = {
+	200000000,
+	200000000,
+	200000000,
+	200000000,
+};
+#else
+static int mdp_core_clk_rate_table[] = {
+	85330000,
+	85330000,
+	160000000,
+	200000000,
+};
+#endif
+
+static struct msm_panel_common_pdata mdp_pdata = {
+	.gpio = MDP_VSYNC_GPIO,
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+	.mdp_core_clk_rate = 200000000,
+#else
+	.mdp_core_clk_rate = 85330000,
+#endif
+	.mdp_core_clk_table = mdp_core_clk_rate_table,
+	.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+#ifdef CONFIG_MSM_BUS_SCALING
+	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
+#endif
+	.mdp_rev = MDP_REV_42,
+	.writeback_offset = writeback_offset,
+};
+
+static struct platform_device mipi_dsi_renesas_panel_device = {
+	.name = "mipi_renesas",
+	.id = 0,
+};
+
+static struct platform_device mipi_dsi_simulator_panel_device = {
+	.name = "mipi_simulator",
+	.id = 0,
+};
+
+#define LPM_CHANNEL0 0
+static int toshiba_gpio[] = {LPM_CHANNEL0};
+
+static struct mipi_dsi_panel_platform_data toshiba_pdata = {
+	.gpio = toshiba_gpio,
+};
+
+static struct platform_device mipi_dsi_toshiba_panel_device = {
+	.name = "mipi_toshiba",
+	.id = 0,
+	.dev = {
+		.platform_data = &toshiba_pdata,
+	}
+};
+
+#define FPGA_3D_GPIO_CONFIG_ADDR	0xB5
+static int dsi2lvds_gpio[2] = {
+	0,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
+	0x1F08 /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
+	};
+
+static struct msm_panel_common_pdata mipi_dsi2lvds_pdata = {
+	.gpio_num = dsi2lvds_gpio,
+};
+
+static struct mipi_dsi_phy_ctrl dsi_novatek_cmd_mode_phy_db = {
+
+/* DSI_BIT_CLK at 500MHz, 2 lane, RGB888 */
+	{0x0F, 0x0a, 0x04, 0x00, 0x20},	/* regulator */
+	/* timing   */
+	{0xab, 0x8a, 0x18, 0x00, 0x92, 0x97, 0x1b, 0x8c,
+	0x0c, 0x03, 0x04, 0xa0},
+	{0x5f, 0x00, 0x00, 0x10},	/* phy ctrl */
+	{0xff, 0x00, 0x06, 0x00},	/* strength */
+	/* pll control */
+	{0x40, 0xf9, 0x30, 0xda, 0x00, 0x40, 0x03, 0x62,
+	0x40, 0x07, 0x03,
+	0x00, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01},
+};
+
+static struct mipi_dsi_panel_platform_data novatek_pdata = {
+	.fpga_3d_config_addr  = FPGA_3D_GPIO_CONFIG_ADDR,
+	.fpga_ctrl_mode = FPGA_SPI_INTF,
+	.phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
+};
+
+static struct platform_device mipi_dsi_novatek_panel_device = {
+	.name = "mipi_novatek",
+	.id = 0,
+	.dev = {
+		.platform_data = &novatek_pdata,
+	}
+};
+
+static struct platform_device mipi_dsi2lvds_bridge_device = {
+	.name = "mipi_tc358764",
+	.id = 0,
+	.dev.platform_data = &mipi_dsi2lvds_pdata,
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct resource hdmi_msm_resources[] = {
+	{
+		.name  = "hdmi_msm_qfprom_addr",
+		.start = 0x00700000,
+		.end   = 0x007060FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.name  = "hdmi_msm_hdmi_addr",
+		.start = 0x04A00000,
+		.end   = 0x04A00FFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.name  = "hdmi_msm_irq",
+		.start = HDMI_IRQ,
+		.end   = HDMI_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static int hdmi_enable_5v(int on);
+static int hdmi_core_power(int on, int show);
+static int hdmi_cec_power(int on);
+
+static struct msm_hdmi_platform_data hdmi_msm_data = {
+	.irq = HDMI_IRQ,
+	.enable_5v = hdmi_enable_5v,
+	.core_power = hdmi_core_power,
+	.cec_power = hdmi_cec_power,
+};
+
+static struct platform_device hdmi_msm_device = {
+	.name = "hdmi_msm",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(hdmi_msm_resources),
+	.resource = hdmi_msm_resources,
+	.dev.platform_data = &hdmi_msm_data,
+};
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
+
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+static struct platform_device wfd_panel_device = {
+	.name = "wfd_panel",
+	.id = 0,
+	.dev.platform_data = NULL,
+};
+
+static struct platform_device wfd_device = {
+	.name          = "msm_wfd",
+	.id            = -1,
+};
+#endif
+
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors dtv_bus_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+#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,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 566092800 * 2,
+		.ib = 707616000 * 2,
+	},
+};
+#endif
+
+static struct msm_bus_paths dtv_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(dtv_bus_init_vectors),
+		dtv_bus_init_vectors,
+	},
+	{
+		ARRAY_SIZE(dtv_bus_def_vectors),
+		dtv_bus_def_vectors,
+	},
+};
+static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
+	dtv_bus_scale_usecases,
+	ARRAY_SIZE(dtv_bus_scale_usecases),
+	.name = "dtv",
+};
+
+static struct lcdc_platform_data dtv_pdata = {
+	.bus_scale_table = &dtv_bus_scale_pdata,
+};
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static int hdmi_enable_5v(int on)
+{
+	/* TBD: PM8921 regulator instead of 8901 */
+	static struct regulator *reg_8921_hdmi_mvs;	/* HDMI_5V */
+	static int prev_on;
+	int rc;
+
+	if (on == prev_on)
+		return 0;
+
+	if (!reg_8921_hdmi_mvs)
+		reg_8921_hdmi_mvs = regulator_get(&hdmi_msm_device.dev,
+			"hdmi_mvs");
+
+	if (on) {
+		rc = regulator_enable(reg_8921_hdmi_mvs);
+		if (rc) {
+			pr_err("'%s' regulator enable failed, rc=%d\n",
+				"8921_hdmi_mvs", rc);
+			return rc;
+		}
+		pr_debug("%s(on): success\n", __func__);
+	} else {
+		rc = regulator_disable(reg_8921_hdmi_mvs);
+		if (rc)
+			pr_warning("'%s' regulator disable failed, rc=%d\n",
+				"8921_hdmi_mvs", rc);
+		pr_debug("%s(off): success\n", __func__);
+	}
+
+	prev_on = on;
+
+	return 0;
+}
+
+static int hdmi_core_power(int on, int show)
+{
+	static struct regulator *reg_8921_l23, *reg_8921_s4;
+	static int prev_on;
+	int rc;
+
+	if (on == prev_on)
+		return 0;
+
+	/* TBD: PM8921 regulator instead of 8901 */
+	if (!reg_8921_l23) {
+		reg_8921_l23 = regulator_get(&hdmi_msm_device.dev, "hdmi_avdd");
+		if (IS_ERR(reg_8921_l23)) {
+			pr_err("could not get reg_8921_l23, rc = %ld\n",
+				PTR_ERR(reg_8921_l23));
+			return -ENODEV;
+		}
+		rc = regulator_set_voltage(reg_8921_l23, 1800000, 1800000);
+		if (rc) {
+			pr_err("set_voltage failed for 8921_l23, rc=%d\n", rc);
+			return -EINVAL;
+		}
+	}
+	if (!reg_8921_s4) {
+		reg_8921_s4 = regulator_get(&hdmi_msm_device.dev, "hdmi_vcc");
+		if (IS_ERR(reg_8921_s4)) {
+			pr_err("could not get reg_8921_s4, rc = %ld\n",
+				PTR_ERR(reg_8921_s4));
+			return -ENODEV;
+		}
+		rc = regulator_set_voltage(reg_8921_s4, 1800000, 1800000);
+		if (rc) {
+			pr_err("set_voltage failed for 8921_s4, rc=%d\n", rc);
+			return -EINVAL;
+		}
+	}
+
+	if (on) {
+		rc = regulator_set_optimum_mode(reg_8921_l23, 100000);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		rc = regulator_enable(reg_8921_l23);
+		if (rc) {
+			pr_err("'%s' regulator enable failed, rc=%d\n",
+				"hdmi_avdd", rc);
+			return rc;
+		}
+		rc = regulator_enable(reg_8921_s4);
+		if (rc) {
+			pr_err("'%s' regulator enable failed, rc=%d\n",
+				"hdmi_vcc", rc);
+			return rc;
+		}
+		rc = gpio_request(100, "HDMI_DDC_CLK");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_DDC_CLK", 100, rc);
+			goto error1;
+		}
+		rc = gpio_request(101, "HDMI_DDC_DATA");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_DDC_DATA", 101, rc);
+			goto error2;
+		}
+		rc = gpio_request(102, "HDMI_HPD");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_HPD", 102, rc);
+			goto error3;
+		}
+		pr_debug("%s(on): success\n", __func__);
+	} else {
+		gpio_free(100);
+		gpio_free(101);
+		gpio_free(102);
+
+		rc = regulator_disable(reg_8921_l23);
+		if (rc) {
+			pr_err("disable reg_8921_l23 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_disable(reg_8921_s4);
+		if (rc) {
+			pr_err("disable reg_8921_s4 failed, rc=%d\n", rc);
+			return -ENODEV;
+		}
+		rc = regulator_set_optimum_mode(reg_8921_l23, 100);
+		if (rc < 0) {
+			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
+			return -EINVAL;
+		}
+		pr_debug("%s(off): success\n", __func__);
+	}
+
+	prev_on = on;
+
+	return 0;
+
+error3:
+	gpio_free(101);
+error2:
+	gpio_free(100);
+error1:
+	regulator_disable(reg_8921_l23);
+	regulator_disable(reg_8921_s4);
+	return rc;
+}
+
+static int hdmi_cec_power(int on)
+{
+	static int prev_on;
+	int rc;
+
+	if (on == prev_on)
+		return 0;
+
+	if (on) {
+		rc = gpio_request(99, "HDMI_CEC_VAR");
+		if (rc) {
+			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
+				"HDMI_CEC_VAR", 99, rc);
+			goto error;
+		}
+		pr_debug("%s(on): success\n", __func__);
+	} else {
+		gpio_free(99);
+		pr_debug("%s(off): success\n", __func__);
+	}
+
+	prev_on = on;
+
+	return 0;
+error:
+	return rc;
+}
+#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
+
+void __init msm8960_init_fb(void)
+{
+	platform_device_register(&msm_fb_device);
+
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+	platform_device_register(&wfd_panel_device);
+	platform_device_register(&wfd_device);
+#endif
+
+	if (machine_is_msm8960_sim())
+		platform_device_register(&mipi_dsi_simulator_panel_device);
+
+	if (machine_is_msm8960_rumi3())
+		platform_device_register(&mipi_dsi_renesas_panel_device);
+
+	if (!machine_is_msm8960_sim() && !machine_is_msm8960_rumi3()) {
+		platform_device_register(&mipi_dsi_novatek_panel_device);
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+		platform_device_register(&hdmi_msm_device);
+#endif
+	}
+
+	if (machine_is_msm8960_liquid())
+		platform_device_register(&mipi_dsi2lvds_bridge_device);
+	else
+		platform_device_register(&mipi_dsi_toshiba_panel_device);
+
+	if (machine_is_msm8x60_rumi3()) {
+		msm_fb_register_device("mdp", NULL);
+		mipi_dsi_pdata.target_type = 1;
+	} else
+		msm_fb_register_device("mdp", &mdp_pdata);
+	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
+#ifdef CONFIG_MSM_BUS_SCALING
+	msm_fb_register_device("dtv", &dtv_pdata);
+#endif
+}
+
+void __init msm8960_allocate_fb_region(void)
+{
+	void *addr;
+	unsigned long size;
+
+	size = MSM_FB_SIZE;
+	addr = alloc_bootmem_align(size, 0x1000);
+	msm_fb_resources[0].start = __pa(addr);
+	msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
+	pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
+			size, addr, __pa(addr));
+}
diff --git a/arch/arm/mach-msm/board-8960-gpiomux.c b/arch/arm/mach-msm/board-8960-gpiomux.c
new file mode 100644
index 0000000..9be65bb
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960-gpiomux.c
@@ -0,0 +1,662 @@
+/* Copyright (c) 2011, 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 <asm/mach-types.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/socinfo.h>
+#include "devices.h"
+#include "board-8960.h"
+
+/* The SPI configurations apply to GSBI 1*/
+static struct gpiomux_setting spi_active = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_12MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting spi_active_config2 = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config2 = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting gsbi3_suspended_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting gsbi3_active_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi5 = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi10 = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gsbi12 = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting cdc_mclk = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting audio_auxpcm[] = {
+	/* Suspended state */
+	{
+		.func = GPIOMUX_FUNC_GPIO,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+	/* Active state */
+	{
+		.func = GPIOMUX_FUNC_1,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+};
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct gpiomux_setting gpio_eth_config = {
+	.pull = GPIOMUX_PULL_NONE,
+	.drv = GPIOMUX_DRV_8MA,
+	.func = GPIOMUX_FUNC_GPIO,
+};
+#endif
+
+static struct gpiomux_setting slimbus = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_KEEPER,
+};
+
+static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv  = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting wcnss_5wire_active_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv  = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_resout_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_resout_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_sleep_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_sleep_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting cyts_int_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting cyts_int_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct gpiomux_setting hsic_act_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_12MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting hsic_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+	.dir = GPIOMUX_OUT_LOW,
+};
+
+static struct gpiomux_setting hsic_hub_act_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+#endif
+
+static struct gpiomux_setting hap_lvl_shft_suspended_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hap_lvl_shft_active_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting ap2mdm_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdm2ap_status_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdm2ap_errfatal_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_16MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdp_vsync_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdp_vsync_active_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct gpiomux_setting hdmi_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hdmi_active_1_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting hdmi_active_2_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+#endif
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct msm_gpiomux_config msm8960_ethernet_configs[] = {
+	{
+		.gpio = 90,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
+		}
+	},
+	{
+		.gpio = 89,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
+		}
+	},
+};
+#endif
+
+static struct msm_gpiomux_config msm8960_gsbi_configs[] __initdata = {
+	{
+		.gpio      = 6,		/* GSBI1 QUP SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 7,		/* GSBI1 QUP SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 8,		/* GSBI1 QUP SPI_CS_N */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 9,		/* GSBI1 QUP SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
+			[GPIOMUX_ACTIVE] = &spi_active,
+		},
+	},
+	{
+		.gpio      = 14,		/* GSBI1 SPI_CS_1 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config2,
+			[GPIOMUX_ACTIVE] = &spi_active_config2,
+		},
+	},
+	{
+		.gpio      = 16,	/* GSBI3 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+		},
+	},
+	{
+		.gpio      = 17,	/* GSBI3 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
+			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
+		},
+	},
+	{
+		.gpio      = 22,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 23,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 24,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 25,	/* GSBI5 UART2 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi5,
+		},
+	},
+	{
+		.gpio      = 44,	/* GSBI12 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi12,
+		},
+	},
+	{
+		.gpio      = 45,	/* GSBI12 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi12,
+		},
+	},
+	{
+		.gpio      = 73,	/* GSBI10 I2C QUP SDA */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi10,
+		},
+	},
+	{
+		.gpio      = 74,	/* GSBI10 I2C QUP SCL */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gsbi10,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
+	{
+		.gpio	= 60,		/* slimbus data */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &slimbus,
+		},
+	},
+	{
+		.gpio	= 61,		/* slimbus clk */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &slimbus,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_audio_codec_configs[] __initdata = {
+	{
+		.gpio = 59,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &cdc_mclk,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
+	{
+		.gpio = 63,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 64,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 65,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 66,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+};
+
+static struct msm_gpiomux_config wcnss_5wire_interface[] = {
+	{
+		.gpio = 84,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 85,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 86,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 87,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 88,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+};
+
+static struct msm_gpiomux_config msm8960_cyts_configs[] __initdata = {
+	{	/* TS INTERRUPT */
+		.gpio = 11,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cyts_int_act_cfg,
+			[GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
+		},
+	},
+	{	/* TS SLEEP */
+		.gpio = 50,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cyts_sleep_act_cfg,
+			[GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
+		},
+	},
+	{	/* TS RESOUT */
+		.gpio = 52,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &cyts_resout_act_cfg,
+			[GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
+		},
+	},
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct msm_gpiomux_config msm8960_hsic_configs[] = {
+	{
+		.gpio = 150,               /*HSIC_STROBE */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+	{
+		.gpio = 151,               /* HSIC_DATA */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+	{
+		.gpio = 91,               /* HSIC_HUB_RESET */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+};
+#endif
+
+static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
+	{
+		.gpio = 47,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
+			[GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
+		},
+	},
+};
+
+static struct msm_gpiomux_config mdm_configs[] __initdata = {
+	/* AP2MDM_STATUS */
+	{
+		.gpio = 94,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* MDM2AP_STATUS */
+	{
+		.gpio = 69,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+		}
+	},
+	/* MDM2AP_ERRFATAL */
+	{
+		.gpio = 70,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+		}
+	},
+	/* AP2MDM_ERRFATAL */
+	{
+		.gpio = 95,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* AP2MDM_KPDPWR_N */
+	{
+		.gpio = 81,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+		}
+	},
+	/* AP2MDM_PMIC_RESET_N */
+	{
+		.gpio = 80,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
+		}
+	}
+};
+
+static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
+	{
+		.gpio = 0,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &mdp_vsync_active_cfg,
+			[GPIOMUX_SUSPENDED] = &mdp_vsync_suspend_cfg,
+		},
+	}
+};
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+static struct msm_gpiomux_config msm8960_hdmi_configs[] __initdata = {
+	{
+		.gpio = 99,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 100,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 101,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 102,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &hdmi_active_2_cfg,
+			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+		},
+	},
+};
+#endif
+
+int __init msm8960_init_gpiomux(void)
+{
+	int rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	if (rc) {
+		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
+		return rc;
+	}
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+	msm_gpiomux_install(msm8960_ethernet_configs,
+			ARRAY_SIZE(msm8960_ethernet_configs));
+#endif
+
+	msm_gpiomux_install(msm8960_gsbi_configs,
+			ARRAY_SIZE(msm8960_gsbi_configs));
+
+	msm_gpiomux_install(msm8960_cyts_configs,
+			ARRAY_SIZE(msm8960_cyts_configs));
+
+	msm_gpiomux_install(msm8960_slimbus_config,
+			ARRAY_SIZE(msm8960_slimbus_config));
+
+	msm_gpiomux_install(msm8960_audio_codec_configs,
+			ARRAY_SIZE(msm8960_audio_codec_configs));
+
+	msm_gpiomux_install(msm8960_audio_auxpcm_configs,
+			ARRAY_SIZE(msm8960_audio_auxpcm_configs));
+
+	msm_gpiomux_install(wcnss_5wire_interface,
+			ARRAY_SIZE(wcnss_5wire_interface));
+
+	if (machine_is_msm8960_mtp() || machine_is_msm8960_fluid() ||
+		machine_is_msm8960_liquid() || machine_is_msm8960_cdp())
+		msm_gpiomux_install(hap_lvl_shft_config,
+			ARRAY_SIZE(hap_lvl_shft_config));
+
+	if (PLATFORM_IS_CHARM25())
+		msm_gpiomux_install(mdm_configs,
+			ARRAY_SIZE(mdm_configs));
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+	if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1) &&
+		(PLATFORM_IS_CHARM25() || machine_is_msm8960_liquid()))
+		msm_gpiomux_install(msm8960_hsic_configs,
+			ARRAY_SIZE(msm8960_hsic_configs));
+#endif
+
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
+	msm_gpiomux_install(msm8960_hdmi_configs,
+			ARRAY_SIZE(msm8960_hdmi_configs));
+#endif
+
+	msm_gpiomux_install(msm8960_mdp_vsync_configs,
+			ARRAY_SIZE(msm8960_mdp_vsync_configs));
+
+	return 0;
+}
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
new file mode 100644
index 0000000..44f7be6
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -0,0 +1,542 @@
+/* Copyright (c) 2011, 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/interrupt.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
+#include <linux/msm_ssbi.h>
+#include <asm/mach-types.h>
+#include <mach/msm_bus_board.h>
+#include <mach/restart.h>
+#include "devices.h"
+#include "board-8960.h"
+
+struct pm8xxx_gpio_init {
+	unsigned			gpio;
+	struct pm_gpio			config;
+};
+
+struct pm8xxx_mpp_init {
+	unsigned			mpp;
+	struct pm8xxx_mpp_config_data	config;
+};
+
+#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+			_func, _inv, _disable) \
+{ \
+	.gpio	= PM8921_GPIO_PM_TO_SYS(_gpio), \
+	.config	= { \
+		.direction	= _dir, \
+		.output_buffer	= _buf, \
+		.output_value	= _val, \
+		.pull		= _pull, \
+		.vin_sel	= _vin, \
+		.out_strength	= _out_strength, \
+		.function	= _func, \
+		.inv_int_pol	= _inv, \
+		.disable_pin	= _disable, \
+	} \
+}
+
+#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8921_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
+
+#define PM8XXX_GPIO_DISABLE(_gpio) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+			 0, 0, 0, 1)
+
+#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+			_pull, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_NO, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8XXX_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_HIGH, \
+			_func, 0, 0)
+
+#define PM8XXX_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, _vin, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+/* Initial PM8921 GPIO configurations */
+static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
+	PM8XXX_GPIO_DISABLE(6),				 /* Disable unused */
+	PM8XXX_GPIO_DISABLE(7),				 /* Disable NFC */
+	PM8XXX_GPIO_INPUT(16,	    PM_GPIO_PULL_UP_30), /* SD_CARD_WP */
+    /* External regulator shared by display and touchscreen on LiQUID */
+	PM8XXX_GPIO_OUTPUT(17,	    0),			 /* DISP 3.3 V Boost */
+	PM8XXX_GPIO_OUTPUT_VIN(21, 1, PM_GPIO_VIN_VPH),	 /* Backlight Enable */
+	PM8XXX_GPIO_DISABLE(22),			 /* Disable NFC */
+	PM8XXX_GPIO_OUTPUT_FUNC(24, 0, PM_GPIO_FUNC_2),	 /* Bl: Off, PWM mode */
+	PM8XXX_GPIO_INPUT(26,	    PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
+	PM8XXX_GPIO_OUTPUT(43,	    PM_GPIO_PULL_UP_30), /* DISP_RESET_N */
+	PM8XXX_GPIO_OUTPUT(42, 0),                      /* USB 5V reg enable */
+};
+
+/* Initial PM8921 MPP configurations */
+static struct pm8xxx_mpp_init pm8921_mpps[] __initdata = {
+	/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
+	PM8XXX_MPP_INIT(7, D_INPUT, PM8921_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
+	PM8XXX_MPP_INIT(PM8XXX_AMUX_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
+								DOUT_CTRL_LOW),
+};
+
+void __init msm8960_pm8921_gpio_mpp_init(void)
+{
+	int i, rc;
+
+	for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
+		rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
+					&pm8921_gpios[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pm8921_mpps); i++) {
+		rc = pm8xxx_mpp_config(pm8921_mpps[i].mpp,
+					&pm8921_mpps[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+}
+
+static struct pm8xxx_adc_amux pm8xxx_adc_channels_data[] = {
+	{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
+	{"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
+	{"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"pa_therm1", ADC_MPP_1_AMUX8, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+	{"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
+	{"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
+};
+
+static struct pm8xxx_adc_properties pm8xxx_adc_data = {
+	.adc_vdd_reference	= 1800, /* milli-voltage for this adc */
+	.bitresolution		= 15,
+	.bipolar                = 0,
+};
+
+static struct pm8xxx_adc_platform_data pm8xxx_adc_pdata = {
+	.adc_channel            = pm8xxx_adc_channels_data,
+	.adc_num_board_channel  = ARRAY_SIZE(pm8xxx_adc_channels_data),
+	.adc_prop               = &pm8xxx_adc_data,
+	.adc_mpp_base		= PM8921_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata __devinitdata = {
+	.irq_base		= PM8921_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(104),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
+};
+
+static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata __devinitdata = {
+	.gpio_base	= PM8921_GPIO_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata __devinitdata = {
+	.mpp_base	= PM8921_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_rtc_platform_data pm8xxx_rtc_pdata __devinitdata = {
+	.rtc_write_enable       = false,
+	.rtc_alarm_powerup	= false,
+};
+
+static struct pm8xxx_pwrkey_platform_data pm8xxx_pwrkey_pdata = {
+	.pull_up		= 1,
+	.kpd_trigger_delay_us	= 15625,
+	.wakeup			= 1,
+};
+
+/* Rotate lock key is not available so use F1 */
+#define KEY_ROTATE_LOCK KEY_F1
+
+static const unsigned int keymap_liquid[] = {
+	KEY(0, 0, KEY_VOLUMEUP),
+	KEY(0, 1, KEY_VOLUMEDOWN),
+	KEY(1, 3, KEY_ROTATE_LOCK),
+	KEY(1, 4, KEY_HOME),
+};
+
+static struct matrix_keymap_data keymap_data_liquid = {
+	.keymap_size    = ARRAY_SIZE(keymap_liquid),
+	.keymap         = keymap_liquid,
+};
+
+static struct pm8xxx_keypad_platform_data keypad_data_liquid = {
+	.input_name             = "keypad_8960_liquid",
+	.input_phys_device      = "keypad_8960/input0",
+	.num_rows               = 2,
+	.num_cols               = 5,
+	.rows_gpio_start	= PM8921_GPIO_PM_TO_SYS(9),
+	.cols_gpio_start	= PM8921_GPIO_PM_TO_SYS(1),
+	.debounce_ms            = 15,
+	.scan_delay_ms          = 32,
+	.row_hold_ns            = 91500,
+	.wakeup                 = 1,
+	.keymap_data            = &keymap_data_liquid,
+};
+
+
+static const unsigned int keymap[] = {
+	KEY(0, 0, KEY_VOLUMEUP),
+	KEY(0, 1, KEY_VOLUMEDOWN),
+	KEY(0, 2, KEY_CAMERA_SNAPSHOT),
+	KEY(0, 3, KEY_CAMERA_FOCUS),
+};
+
+static struct matrix_keymap_data keymap_data = {
+	.keymap_size    = ARRAY_SIZE(keymap),
+	.keymap         = keymap,
+};
+
+static struct pm8xxx_keypad_platform_data keypad_data = {
+	.input_name             = "keypad_8960",
+	.input_phys_device      = "keypad_8960/input0",
+	.num_rows               = 1,
+	.num_cols               = 5,
+	.rows_gpio_start	= PM8921_GPIO_PM_TO_SYS(9),
+	.cols_gpio_start	= PM8921_GPIO_PM_TO_SYS(1),
+	.debounce_ms            = 15,
+	.scan_delay_ms          = 32,
+	.row_hold_ns            = 91500,
+	.wakeup                 = 1,
+	.keymap_data            = &keymap_data,
+};
+
+static const unsigned int keymap_sim[] = {
+	KEY(0, 0, KEY_7),
+	KEY(0, 1, KEY_DOWN),
+	KEY(0, 2, KEY_UP),
+	KEY(0, 3, KEY_RIGHT),
+	KEY(0, 4, KEY_ENTER),
+	KEY(0, 5, KEY_L),
+	KEY(0, 6, KEY_BACK),
+	KEY(0, 7, KEY_M),
+
+	KEY(1, 0, KEY_LEFT),
+	KEY(1, 1, KEY_SEND),
+	KEY(1, 2, KEY_1),
+	KEY(1, 3, KEY_4),
+	KEY(1, 4, KEY_CLEAR),
+	KEY(1, 5, KEY_MSDOS),
+	KEY(1, 6, KEY_SPACE),
+	KEY(1, 7, KEY_COMMA),
+
+	KEY(2, 0, KEY_6),
+	KEY(2, 1, KEY_5),
+	KEY(2, 2, KEY_8),
+	KEY(2, 3, KEY_3),
+	KEY(2, 4, KEY_NUMERIC_STAR),
+	KEY(2, 5, KEY_UP),
+	KEY(2, 6, KEY_DOWN),
+	KEY(2, 7, KEY_LEFTSHIFT),
+
+	KEY(3, 0, KEY_9),
+	KEY(3, 1, KEY_NUMERIC_POUND),
+	KEY(3, 2, KEY_0),
+	KEY(3, 3, KEY_2),
+	KEY(3, 4, KEY_SLEEP),
+	KEY(3, 5, KEY_F1),
+	KEY(3, 6, KEY_F2),
+	KEY(3, 7, KEY_F3),
+
+	KEY(4, 0, KEY_BACK),
+	KEY(4, 1, KEY_HOME),
+	KEY(4, 2, KEY_MENU),
+	KEY(4, 3, KEY_VOLUMEUP),
+	KEY(4, 4, KEY_VOLUMEDOWN),
+	KEY(4, 5, KEY_F4),
+	KEY(4, 6, KEY_F5),
+	KEY(4, 7, KEY_F6),
+
+	KEY(5, 0, KEY_R),
+	KEY(5, 1, KEY_T),
+	KEY(5, 2, KEY_Y),
+	KEY(5, 3, KEY_LEFTALT),
+	KEY(5, 4, KEY_KPENTER),
+	KEY(5, 5, KEY_Q),
+	KEY(5, 6, KEY_W),
+	KEY(5, 7, KEY_E),
+
+	KEY(6, 0, KEY_F),
+	KEY(6, 1, KEY_G),
+	KEY(6, 2, KEY_H),
+	KEY(6, 3, KEY_CAPSLOCK),
+	KEY(6, 4, KEY_PAGEUP),
+	KEY(6, 5, KEY_A),
+	KEY(6, 6, KEY_S),
+	KEY(6, 7, KEY_D),
+
+	KEY(7, 0, KEY_V),
+	KEY(7, 1, KEY_B),
+	KEY(7, 2, KEY_N),
+	KEY(7, 3, KEY_MENU),
+	KEY(7, 4, KEY_PAGEDOWN),
+	KEY(7, 5, KEY_Z),
+	KEY(7, 6, KEY_X),
+	KEY(7, 7, KEY_C),
+
+	KEY(8, 0, KEY_P),
+	KEY(8, 1, KEY_J),
+	KEY(8, 2, KEY_K),
+	KEY(8, 3, KEY_INSERT),
+	KEY(8, 4, KEY_LINEFEED),
+	KEY(8, 5, KEY_U),
+	KEY(8, 6, KEY_I),
+	KEY(8, 7, KEY_O),
+
+	KEY(9, 0, KEY_4),
+	KEY(9, 1, KEY_5),
+	KEY(9, 2, KEY_6),
+	KEY(9, 3, KEY_7),
+	KEY(9, 4, KEY_8),
+	KEY(9, 5, KEY_1),
+	KEY(9, 6, KEY_2),
+	KEY(9, 7, KEY_3),
+
+	KEY(10, 0, KEY_F7),
+	KEY(10, 1, KEY_F8),
+	KEY(10, 2, KEY_F9),
+	KEY(10, 3, KEY_F10),
+	KEY(10, 4, KEY_FN),
+	KEY(10, 5, KEY_9),
+	KEY(10, 6, KEY_0),
+	KEY(10, 7, KEY_DOT),
+
+	KEY(11, 0, KEY_LEFTCTRL),
+	KEY(11, 1, KEY_F11),
+	KEY(11, 2, KEY_ENTER),
+	KEY(11, 3, KEY_SEARCH),
+	KEY(11, 4, KEY_DELETE),
+	KEY(11, 5, KEY_RIGHT),
+	KEY(11, 6, KEY_LEFT),
+	KEY(11, 7, KEY_RIGHTSHIFT),
+	KEY(0, 0, KEY_VOLUMEUP),
+	KEY(0, 1, KEY_VOLUMEDOWN),
+	KEY(0, 2, KEY_CAMERA_SNAPSHOT),
+	KEY(0, 3, KEY_CAMERA_FOCUS),
+};
+
+static struct matrix_keymap_data keymap_data_sim = {
+	.keymap_size    = ARRAY_SIZE(keymap_sim),
+	.keymap         = keymap_sim,
+};
+
+static struct pm8xxx_keypad_platform_data keypad_data_sim = {
+	.input_name             = "keypad_8960",
+	.input_phys_device      = "keypad_8960/input0",
+	.num_rows               = 12,
+	.num_cols               = 8,
+	.rows_gpio_start	= PM8921_GPIO_PM_TO_SYS(9),
+	.cols_gpio_start	= PM8921_GPIO_PM_TO_SYS(1),
+	.debounce_ms            = 15,
+	.scan_delay_ms          = 32,
+	.row_hold_ns            = 91500,
+	.wakeup                 = 1,
+	.keymap_data            = &keymap_data_sim,
+};
+
+static int pm8921_therm_mitigation[] = {
+	1100,
+	700,
+	600,
+	325,
+};
+
+static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
+	.safety_time		= 180,
+	.update_time		= 60000,
+	.max_voltage		= 4200,
+	.min_voltage		= 3200,
+	.resume_voltage_delta	= 100,
+	.term_current		= 100,
+	.cool_temp		= 10,
+	.warm_temp		= 40,
+	.temp_check_period	= 1,
+	.max_bat_chg_current	= 1100,
+	.cool_bat_chg_current	= 350,
+	.warm_bat_chg_current	= 350,
+	.cool_bat_voltage	= 4100,
+	.warm_bat_voltage	= 4100,
+	.thermal_mitigation	= pm8921_therm_mitigation,
+	.thermal_levels		= ARRAY_SIZE(pm8921_therm_mitigation),
+};
+
+static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
+	.priority		= 0,
+};
+
+static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
+	.r_sense		= 10,
+	.i_test			= 2500,
+	.v_failure		= 3000,
+	.calib_delay_ms		= 600000,
+};
+
+#define	PM8921_LC_LED_MAX_CURRENT	4	/* I = 4mA */
+#define PM8XXX_LED_PWM_PERIOD		1000
+#define PM8XXX_LED_PWM_DUTY_MS		20
+/**
+ * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
+ * driven using PWM feature.
+ */
+#define PM8XXX_PWM_CHANNEL_NONE		-1
+
+static struct led_info pm8921_led_info[] = {
+	[0] = {
+		.name			= "led:battery_charging",
+		.default_trigger	= "battery-charging",
+	},
+	[1] = {
+		.name			= "led:battery_full",
+		.default_trigger	= "battery-full",
+	},
+};
+
+static struct led_platform_data pm8921_led_core_pdata = {
+	.num_leds = ARRAY_SIZE(pm8921_led_info),
+	.leds = pm8921_led_info,
+};
+
+static int pm8921_led0_pwm_duty_pcts[56] = {
+		1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+		40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
+		80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
+		92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
+		58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
+		14, 10, 6, 4, 1
+};
+
+static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
+	.duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
+	.num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
+	.duty_ms = PM8XXX_LED_PWM_DUTY_MS,
+	.start_idx = 0,
+};
+
+static struct pm8xxx_led_config pm8921_led_configs[] = {
+	[0] = {
+		.id = PM8XXX_ID_LED_0,
+		.mode = PM8XXX_LED_MODE_PWM2,
+		.max_current = PM8921_LC_LED_MAX_CURRENT,
+		.pwm_channel = 5,
+		.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
+		.pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
+	},
+	[1] = {
+		.id = PM8XXX_ID_LED_1,
+		.mode = PM8XXX_LED_MODE_PWM1,
+		.max_current = PM8921_LC_LED_MAX_CURRENT,
+		.pwm_channel = 4,
+		.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
+	},
+};
+
+static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
+		.led_core = &pm8921_led_core_pdata,
+		.configs = pm8921_led_configs,
+		.num_configs = ARRAY_SIZE(pm8921_led_configs),
+};
+
+static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
+	.r_sense		= 10,
+};
+
+static struct pm8921_platform_data pm8921_platform_data __devinitdata = {
+	.irq_pdata		= &pm8xxx_irq_pdata,
+	.gpio_pdata		= &pm8xxx_gpio_pdata,
+	.mpp_pdata		= &pm8xxx_mpp_pdata,
+	.rtc_pdata              = &pm8xxx_rtc_pdata,
+	.pwrkey_pdata		= &pm8xxx_pwrkey_pdata,
+	.keypad_pdata		= &keypad_data,
+	.misc_pdata		= &pm8xxx_misc_pdata,
+	.regulator_pdatas	= msm_pm8921_regulator_pdata,
+	.charger_pdata		= &pm8921_chg_pdata,
+	.bms_pdata		= &pm8921_bms_pdata,
+	.adc_pdata		= &pm8xxx_adc_pdata,
+	.leds_pdata		= &pm8xxx_leds_pdata,
+	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
+};
+
+static struct msm_ssbi_platform_data msm8960_ssbi_pm8921_pdata __devinitdata = {
+	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+	.slave	= {
+		.name			= "pm8921-core",
+		.platform_data		= &pm8921_platform_data,
+	},
+};
+
+void __init msm8960_init_pmic(void)
+{
+	pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
+	msm8960_device_ssbi_pm8921.dev.platform_data =
+				&msm8960_ssbi_pm8921_pdata;
+	pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
+
+	/* Simulator supports a QWERTY keypad */
+	if (machine_is_msm8960_sim())
+		pm8921_platform_data.keypad_pdata = &keypad_data_sim;
+
+	if (machine_is_msm8960_liquid())
+		pm8921_platform_data.keypad_pdata = &keypad_data_liquid;
+}
diff --git a/arch/arm/mach-msm/board-msm8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
similarity index 98%
rename from arch/arm/mach-msm/board-msm8960-regulator.c
rename to arch/arm/mach-msm/board-8960-regulator.c
index 559312c..7bc3ca5 100644
--- a/arch/arm/mach-msm/board-msm8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -15,7 +15,7 @@
 #include <linux/regulator/gpio-regulator.h>
 #include <mach/rpm-regulator.h>
 
-#include "board-msm8960.h"
+#include "board-8960.h"
 
 #define VREG_CONSUMERS(_id) \
 	static struct regulator_consumer_supply vreg_consumers_##_id[]
@@ -119,15 +119,15 @@
 };
 VREG_CONSUMERS(L26) = {
 	REGULATOR_SUPPLY("8921_l26",		NULL),
-	REGULATOR_SUPPLY("q6_lpass",		NULL),
+	REGULATOR_SUPPLY("core_vdd",		"pil_qdsp6v4.0"),
 };
 VREG_CONSUMERS(L27) = {
 	REGULATOR_SUPPLY("8921_l27",		NULL),
-	REGULATOR_SUPPLY("q6_modem_sw",		NULL),
+	REGULATOR_SUPPLY("core_vdd",		"pil_qdsp6v4.2"),
 };
 VREG_CONSUMERS(L28) = {
 	REGULATOR_SUPPLY("8921_l28",		NULL),
-	REGULATOR_SUPPLY("q6_modem_fw",		NULL),
+	REGULATOR_SUPPLY("core_vdd",		"pil_qdsp6v4.1"),
 };
 VREG_CONSUMERS(L29) = {
 	REGULATOR_SUPPLY("8921_l29",		NULL),
@@ -449,9 +449,9 @@
 /* SAW regulator constraints */
 struct regulator_init_data msm_saw_regulator_pdata_s5 =
 	/*	      ID  vreg_name	       min_uV   max_uV */
-	SAW_VREG_INIT(S5, "8921_s5",	       950000, 1150000);
+	SAW_VREG_INIT(S5, "8921_s5",	       950000, 1300000);
 struct regulator_init_data msm_saw_regulator_pdata_s6 =
-	SAW_VREG_INIT(S6, "8921_s6",	       950000, 1150000);
+	SAW_VREG_INIT(S6, "8921_s6",	       950000, 1300000);
 
 /* PM8921 regulator constraints */
 struct pm8921_regulator_platform_data
diff --git a/arch/arm/mach-msm/board-8960-storage.c b/arch/arm/mach-msm/board-8960-storage.c
new file mode 100644
index 0000000..dfcafd4
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960-storage.c
@@ -0,0 +1,268 @@
+/* Copyright (c) 2011, 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/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <asm/mach-types.h>
+#include <asm/mach/mmc.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include "devices.h"
+#include "board-8960.h"
+
+/* MSM8960 has 5 SDCC controllers */
+enum sdcc_controllers {
+	SDCC1,
+	SDCC2,
+	SDCC3,
+	SDCC4,
+	SDCC5,
+	MAX_SDCC_CONTROLLER
+};
+
+/* All SDCC controllers require VDD/VCC voltage */
+static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.name = "sdc_vdd",
+		.high_vol_level = 2950000,
+		.low_vol_level = 2950000,
+		.always_on = 1,
+		.lpm_sup = 1,
+		.lpm_uA = 9000,
+		.hpm_uA = 200000, /* 200mA */
+	},
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.name = "sdc_vdd",
+		.high_vol_level = 2950000,
+		.low_vol_level = 2950000,
+		.hpm_uA = 600000, /* 600mA */
+	}
+};
+
+/* Only slots having eMMC card will require VCCQ voltage */
+static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.name = "sdc_vccq",
+		.always_on = 1,
+		.high_vol_level = 1800000,
+		.low_vol_level = 1800000,
+		.hpm_uA = 200000, /* 200mA */
+	}
+};
+
+/* All SDCC controllers may require voting for VDD PAD voltage */
+static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.name = "sdc_vddp",
+		.high_vol_level = 2950000,
+		.low_vol_level = 1850000,
+		.always_on = 1,
+		.lpm_sup = 1,
+		/* Max. Active current required is 16 mA */
+		.hpm_uA = 16000,
+		/*
+		 * Sleep current required is ~300 uA. But min. vote can be
+		 * in terms of mA (min. 1 mA). So let's vote for 2 mA
+		 * during sleep.
+		 */
+		.lpm_uA = 2000,
+	}
+};
+
+static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
+	/* SDCC1 : eMMC card connected */
+	[SDCC1] = {
+		.vdd_data = &mmc_vdd_reg_data[SDCC1],
+		.vccq_data = &mmc_vccq_reg_data[SDCC1],
+	},
+	/* SDCC3 : External card slot connected */
+	[SDCC3] = {
+		.vdd_data = &mmc_vdd_reg_data[SDCC3],
+		.vddp_data = &mmc_vddp_reg_data[SDCC3],
+	}
+};
+
+/* SDC1 pad data */
+static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
+	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
+	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
+	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
+};
+
+static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
+	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
+};
+
+static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
+	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
+	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
+	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
+	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
+};
+
+/* SDC3 pad data */
+static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
+	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
+	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
+	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
+};
+
+static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
+	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
+	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
+};
+
+static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
+	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
+	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
+	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
+	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
+	/*
+	 * SDC3 CMD line should be PULLed UP otherwise fluid platform will
+	 * see transitions (1 -> 0 and 0 -> 1) on card detection line,
+	 * which would result in false card detection interrupts.
+	 */
+	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
+	/*
+	 * Keeping DATA lines status to PULL UP will make sure that
+	 * there is no current leak during sleep if external pull up
+	 * is connected to DATA lines.
+	 */
+	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
+};
+
+static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.on = sdc1_pad_pull_on_cfg,
+		.off = sdc1_pad_pull_off_cfg,
+		.size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
+	},
+	[SDCC3] = {
+		.on = sdc3_pad_pull_on_cfg,
+		.off = sdc3_pad_pull_off_cfg,
+		.size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
+	},
+};
+
+static struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.on = sdc1_pad_drv_on_cfg,
+		.off = sdc1_pad_drv_off_cfg,
+		.size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
+	},
+	[SDCC3] = {
+		.on = sdc3_pad_drv_on_cfg,
+		.off = sdc3_pad_drv_off_cfg,
+		.size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
+	},
+};
+
+static struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.pull = &mmc_pad_pull_data[SDCC1],
+		.drv = &mmc_pad_drv_data[SDCC1]
+	},
+	[SDCC3] = {
+		.pull = &mmc_pad_pull_data[SDCC3],
+		.drv = &mmc_pad_drv_data[SDCC3]
+	},
+};
+
+static struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
+	[SDCC1] = {
+		.pad_data = &mmc_pad_data[SDCC1],
+	},
+	[SDCC3] = {
+		.pad_data = &mmc_pad_data[SDCC3],
+	},
+};
+
+static unsigned int sdc1_sup_clk_rates[] = {
+	400000, 24000000, 48000000
+};
+
+static unsigned int sdc3_sup_clk_rates[] = {
+	400000, 24000000, 48000000, 96000000
+};
+
+#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
+static struct mmc_platform_data msm8960_sdc1_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
+	.mmc_bus_width  = MMC_CAP_8_BIT_DATA,
+#else
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+#endif
+	.sup_clk_table	= sdc1_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
+	.pclk_src_dfab	= 1,
+	.nonremovable	= 1,
+	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
+	.pin_data	= &mmc_slot_pin_data[SDCC1]
+};
+#endif
+
+#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
+static struct mmc_platform_data msm8960_sdc3_data = {
+	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
+	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
+	.sup_clk_table	= sdc3_sup_clk_rates,
+	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
+	.pclk_src_dfab	= 1,
+#ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
+	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
+#endif
+	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
+	.pin_data	= &mmc_slot_pin_data[SDCC3],
+#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
+	.status_gpio	= PM8921_GPIO_PM_TO_SYS(26),
+	.status_irq	= PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
+	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+#endif
+	.xpc_cap	= 1,
+	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+			MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
+			MMC_CAP_MAX_CURRENT_600)
+};
+#endif
+
+void __init msm8960_init_mmc(void)
+{
+#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
+	/* SDC1 : eMMC card connected */
+	msm_add_sdcc(1, &msm8960_sdc1_data);
+#endif
+#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
+	/* SDC3: External card slot */
+	msm_add_sdcc(3, &msm8960_sdc3_data);
+#endif
+}
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
new file mode 100644
index 0000000..2b9b0be
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960.c
@@ -0,0 +1,2246 @@
+/* Copyright (c) 2011, 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/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/i2c/sx150x.h>
+#include <linux/i2c/isl9519.h>
+#include <linux/gpio.h>
+#include <linux/msm_ssbi.h>
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+#include <linux/slimbus/slimbus.h>
+#include <linux/bootmem.h>
+#include <linux/msm_kgsl.h>
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+#include <linux/cyttsp.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_data/qcom_crypto_device.h>
+#include <linux/platform_data/qcom_wcnss_device.h>
+#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/msm_tsens.h>
+#include <linux/ks8851.h>
+#include <linux/i2c/isa1200.h>
+#include <linux/memory.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/mmc.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_spi.h>
+#ifdef CONFIG_USB_MSM_OTG_72K
+#include <mach/msm_hsusb.h>
+#else
+#include <linux/usb/msm_hsusb.h>
+#endif
+#include <linux/usb/android.h>
+#include <mach/usbdiag.h>
+#include <mach/socinfo.h>
+#include <mach/rpm.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_bus_board.h>
+#include <mach/msm_memtypes.h>
+#include <mach/dma.h>
+#include <mach/msm_dsps.h>
+#include <mach/msm_xo.h>
+#include <mach/restart.h>
+
+#ifdef CONFIG_WCD9310_CODEC
+#include <linux/slimbus/slimbus.h>
+#include <linux/mfd/wcd9310/core.h>
+#include <linux/mfd/wcd9310/pdata.h>
+#endif
+
+#include <linux/ion.h>
+#include <mach/ion.h>
+#include <mach/mdm2.h>
+
+#include "timer.h"
+#include "devices.h"
+#include "devices-msm8x60.h"
+#include "spm.h"
+#include "board-8960.h"
+#include "pm.h"
+#include "cpuidle.h"
+#include "rpm_resources.h"
+#include "mpm.h"
+#include "acpuclock.h"
+#include "rpm_log.h"
+#include "smd_private.h"
+#include "pm-boot.h"
+#include "msm_watchdog.h"
+
+static struct platform_device msm_fm_platform_init = {
+	.name = "iris_fm",
+	.id   = -1,
+};
+
+#define KS8851_RST_GPIO		89
+#define KS8851_IRQ_GPIO		90
+#define HAP_SHIFT_LVL_OE_GPIO	47
+
+#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
+
+struct sx150x_platform_data msm8960_sx150x_data[] = {
+	[SX150X_CAM] = {
+		.gpio_base         = GPIO_CAM_EXPANDER_BASE,
+		.oscio_is_gpo      = false,
+		.io_pullup_ena     = 0x0,
+		.io_pulldn_ena     = 0xc0,
+		.io_open_drain_ena = 0x0,
+		.irq_summary       = -1,
+	},
+};
+
+#endif
+
+#define MSM_PMEM_ADSP_SIZE         0x3800000
+#define MSM_PMEM_AUDIO_SIZE        0x28B000
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
+#else
+#define MSM_PMEM_SIZE 0x1C00000 /* 28 Mbytes */
+#endif
+
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
+#define MSM_ION_EBI_SIZE	(MSM_PMEM_SIZE + 0x600000)
+#define MSM_ION_ADSP_SIZE	MSM_PMEM_ADSP_SIZE
+#define MSM_ION_HEAP_NUM	5
+#else
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
+#define MSM_ION_HEAP_NUM	2
+#endif
+
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
+static int __init pmem_kernel_ebi1_size_setup(char *p)
+{
+	pmem_kernel_ebi1_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+static unsigned pmem_size = MSM_PMEM_SIZE;
+static int __init pmem_size_setup(char *p)
+{
+	pmem_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_size", pmem_size_setup);
+
+static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
+
+static int __init pmem_adsp_size_setup(char *p)
+{
+	pmem_adsp_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_adsp_size", pmem_adsp_size_setup);
+
+static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE;
+
+static int __init pmem_audio_size_setup(char *p)
+{
+	pmem_audio_size = memparse(p, NULL);
+	return 0;
+}
+early_param("pmem_audio_size", pmem_audio_size_setup);
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+static struct android_pmem_platform_data android_pmem_pdata = {
+	.name = "pmem",
+	.allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
+	.cached = 1,
+	.memory_type = MEMTYPE_EBI1,
+};
+
+static struct platform_device android_pmem_device = {
+	.name = "android_pmem",
+	.id = 0,
+	.dev = {.platform_data = &android_pmem_pdata},
+};
+
+static struct android_pmem_platform_data android_pmem_adsp_pdata = {
+	.name = "pmem_adsp",
+	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
+	.cached = 0,
+	.memory_type = MEMTYPE_EBI1,
+};
+static struct platform_device android_pmem_adsp_device = {
+	.name = "android_pmem",
+	.id = 2,
+	.dev = { .platform_data = &android_pmem_adsp_pdata },
+};
+#endif
+
+static struct android_pmem_platform_data android_pmem_audio_pdata = {
+	.name = "pmem_audio",
+	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
+	.cached = 0,
+	.memory_type = MEMTYPE_EBI1,
+};
+
+static struct platform_device android_pmem_audio_device = {
+	.name = "android_pmem",
+	.id = 4,
+	.dev = { .platform_data = &android_pmem_audio_pdata },
+};
+#endif
+
+#define DSP_RAM_BASE_8960 0x8da00000
+#define DSP_RAM_SIZE_8960 0x1800000
+static int dspcrashd_pdata_8960 = 0xDEADDEAD;
+
+static struct resource resources_dspcrashd_8960[] = {
+	{
+		.name   = "msm_dspcrashd",
+		.start  = DSP_RAM_BASE_8960,
+		.end    = DSP_RAM_BASE_8960 + DSP_RAM_SIZE_8960,
+		.flags  = IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device msm_device_dspcrashd_8960 = {
+	.name           = "msm_dspcrashd",
+	.num_resources  = ARRAY_SIZE(resources_dspcrashd_8960),
+	.resource       = resources_dspcrashd_8960,
+	.dev = { .platform_data = &dspcrashd_pdata_8960 },
+};
+
+static struct memtype_reserve msm8960_reserve_table[] __initdata = {
+	[MEMTYPE_SMI] = {
+	},
+	[MEMTYPE_EBI0] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+	[MEMTYPE_EBI1] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
+
+static void __init size_pmem_devices(void)
+{
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	android_pmem_adsp_pdata.size = pmem_adsp_size;
+	android_pmem_pdata.size = pmem_size;
+#endif
+	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
+#endif
+}
+
+static void __init reserve_memory_for(struct android_pmem_platform_data *p)
+{
+	msm8960_reserve_table[p->memory_type].size += p->size;
+}
+
+static void __init reserve_pmem_memory(void)
+{
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	reserve_memory_for(&android_pmem_adsp_pdata);
+	reserve_memory_for(&android_pmem_pdata);
+#endif
+	reserve_memory_for(&android_pmem_audio_pdata);
+	msm8960_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
+#endif
+}
+
+static int msm8960_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+#ifdef CONFIG_ION_MSM
+static struct ion_platform_data ion_pdata = {
+	.nr = MSM_ION_HEAP_NUM,
+	.heaps = {
+		{
+			.id	= ION_HEAP_SYSTEM_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM,
+			.name	= ION_KMALLOC_HEAP_NAME,
+		},
+		{
+			.id	= ION_HEAP_SYSTEM_CONTIG_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM_CONTIG,
+			.name	= ION_VMALLOC_HEAP_NAME,
+		},
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		{
+			.id	= ION_HEAP_EBI_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_EBI1_HEAP_NAME,
+			.size	= MSM_ION_EBI_SIZE,
+			.memory_type = ION_EBI_TYPE,
+		},
+		{
+			.id	= ION_HEAP_ADSP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_ADSP_HEAP_NAME,
+			.size	= MSM_ION_ADSP_SIZE,
+			.memory_type = ION_EBI_TYPE,
+		},
+		{
+			.id	= ION_HEAP_IOMMU_ID,
+			.type	= ION_HEAP_TYPE_IOMMU,
+			.name	= ION_IOMMU_HEAP_NAME,
+		},
+#endif
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+#endif
+
+static void reserve_ion_memory(void)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_EBI_SIZE;
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_ADSP_SIZE;
+#endif
+}
+static void __init msm8960_calculate_reserve_sizes(void)
+{
+	size_pmem_devices();
+	reserve_pmem_memory();
+	reserve_ion_memory();
+}
+
+static struct reserve_info msm8960_reserve_info __initdata = {
+	.memtype_reserve_table = msm8960_reserve_table,
+	.calculate_reserve_sizes = msm8960_calculate_reserve_sizes,
+	.paddr_to_memtype = msm8960_paddr_to_memtype,
+};
+
+static int msm8960_memory_bank_size(void)
+{
+	return 1<<29;
+}
+
+static void __init locate_unstable_memory(void)
+{
+	struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
+	unsigned long bank_size;
+	unsigned long low, high;
+
+	bank_size = msm8960_memory_bank_size();
+	low = meminfo.bank[0].start;
+	high = mb->start + mb->size;
+
+	/* Check if 32 bit overflow occured */
+	if (high < mb->start)
+		high = ~0UL;
+
+	low &= ~(bank_size - 1);
+
+	if (high - low <= bank_size)
+		return;
+	msm8960_reserve_info.low_unstable_address = high -
+						MIN_MEMORY_BLOCK_SIZE;
+	msm8960_reserve_info.max_unstable_size = MIN_MEMORY_BLOCK_SIZE;
+
+	msm8960_reserve_info.bank_size = bank_size;
+	pr_info("low unstable address %lx max size %lx bank size %lx\n",
+		msm8960_reserve_info.low_unstable_address,
+		msm8960_reserve_info.max_unstable_size,
+		msm8960_reserve_info.bank_size);
+}
+
+static void __init place_movable_zone(void)
+{
+	movable_reserved_start = msm8960_reserve_info.low_unstable_address;
+	movable_reserved_size = msm8960_reserve_info.max_unstable_size;
+	pr_info("movable zone start %lx size %lx\n",
+		movable_reserved_start, movable_reserved_size);
+}
+
+static void __init msm8960_early_memory(void)
+{
+	reserve_info = &msm8960_reserve_info;
+	locate_unstable_memory();
+	place_movable_zone();
+}
+
+static void __init msm8960_reserve(void)
+{
+	msm_reserve();
+}
+
+static int msm8960_change_memory_power(u64 start, u64 size,
+	int change_type)
+{
+	return soc_change_memory_power(start, size, change_type);
+}
+
+static void __init msm8960_allocate_memory_regions(void)
+{
+	msm8960_allocate_fb_region();
+}
+
+#ifdef CONFIG_WCD9310_CODEC
+
+#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_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 tabla_pdata tabla_platform_data = {
+	.slimbus_slave_device = {
+		.name = "tabla-slave",
+		.e_addr = {0, 0, 0x10, 0, 0x17, 2},
+	},
+	.irq = MSM_GPIO_TO_INT(62),
+	.irq_base = TABLA_INTERRUPT_BASE,
+	.num_irqs = NR_TABLA_IRQS,
+	.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+	.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,
+	}
+};
+
+static struct slim_device msm_slim_tabla = {
+	.name = "tabla-slim",
+	.e_addr = {0, 1, 0x10, 0, 0x17, 2},
+	.dev = {
+		.platform_data = &tabla_platform_data,
+	},
+};
+
+static struct tabla_pdata tabla20_platform_data = {
+	.slimbus_slave_device = {
+		.name = "tabla-slave",
+		.e_addr = {0, 0, 0x60, 0, 0x17, 2},
+	},
+	.irq = MSM_GPIO_TO_INT(62),
+	.irq_base = TABLA_INTERRUPT_BASE,
+	.num_irqs = NR_TABLA_IRQS,
+	.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
+	.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,
+	}
+};
+
+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[] = {
+#ifdef CONFIG_WCD9310_CODEC
+	{
+		.bus_num = 1,
+		.slim_slave = &msm_slim_tabla,
+	},
+	{
+		.bus_num = 1,
+		.slim_slave = &msm_slim_tabla20,
+	},
+#endif
+	/* add more slimbus slaves as needed */
+};
+
+#define MSM_WCNSS_PHYS	0x03000000
+#define MSM_WCNSS_SIZE	0x280000
+
+static struct resource resources_wcnss_wlan[] = {
+	{
+		.start	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+		.end	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+		.name	= "wcnss_wlanrx_irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+		.end	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+		.name	= "wcnss_wlantx_irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_WCNSS_PHYS,
+		.end	= MSM_WCNSS_PHYS + MSM_WCNSS_SIZE - 1,
+		.name	= "wcnss_mmio",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 84,
+		.end	= 88,
+		.name	= "wcnss_gpios_5wire",
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct qcom_wcnss_opts qcom_wcnss_pdata = {
+	.has_48mhz_xo	= 1,
+};
+
+static struct platform_device msm_device_wcnss_wlan = {
+	.name		= "wcnss_wlan",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(resources_wcnss_wlan),
+	.resource	= resources_wcnss_wlan,
+	.dev		= {.platform_data = &qcom_wcnss_pdata},
+};
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+
+#define QCE_SIZE		0x10000
+#define QCE_0_BASE		0x18500000
+
+#define QCE_HW_KEY_SUPPORT	0
+#define QCE_SHA_HMAC_SUPPORT	1
+#define QCE_SHARE_CE_RESOURCE	1
+#define QCE_CE_SHARED		0
+
+static struct resource qcrypto_resources[] = {
+	[0] = {
+		.start = QCE_0_BASE,
+		.end = QCE_0_BASE + QCE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.name = "crypto_channels",
+		.start = DMOV_CE_IN_CHAN,
+		.end = DMOV_CE_OUT_CHAN,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.name = "crypto_crci_in",
+		.start = DMOV_CE_IN_CRCI,
+		.end = DMOV_CE_IN_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.name = "crypto_crci_out",
+		.start = DMOV_CE_OUT_CRCI,
+		.end = DMOV_CE_OUT_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static struct resource qcedev_resources[] = {
+	[0] = {
+		.start = QCE_0_BASE,
+		.end = QCE_0_BASE + QCE_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.name = "crypto_channels",
+		.start = DMOV_CE_IN_CHAN,
+		.end = DMOV_CE_OUT_CHAN,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.name = "crypto_crci_in",
+		.start = DMOV_CE_IN_CRCI,
+		.end = DMOV_CE_IN_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.name = "crypto_crci_out",
+		.start = DMOV_CE_OUT_CRCI,
+		.end = DMOV_CE_OUT_CRCI,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+
+static struct msm_ce_hw_support qcrypto_ce_hw_suppport = {
+	.ce_shared = QCE_CE_SHARED,
+	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
+	.hw_key_support = QCE_HW_KEY_SUPPORT,
+	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
+};
+
+static struct platform_device qcrypto_device = {
+	.name		= "qcrypto",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(qcrypto_resources),
+	.resource	= qcrypto_resources,
+	.dev		= {
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &qcrypto_ce_hw_suppport,
+	},
+};
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+
+static struct msm_ce_hw_support qcedev_ce_hw_suppport = {
+	.ce_shared = QCE_CE_SHARED,
+	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
+	.hw_key_support = QCE_HW_KEY_SUPPORT,
+	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
+};
+
+static struct platform_device qcedev_device = {
+	.name		= "qce",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(qcedev_resources),
+	.resource	= qcedev_resources,
+	.dev		= {
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+		.platform_data = &qcedev_ce_hw_suppport,
+	},
+};
+#endif
+
+#define MDM2AP_ERRFATAL			70
+#define AP2MDM_ERRFATAL			95
+#define MDM2AP_STATUS			69
+#define AP2MDM_STATUS			94
+#define AP2MDM_PMIC_RESET_N		80
+#define AP2MDM_KPDPWR_N			81
+
+static struct resource mdm_resources[] = {
+	{
+		.start	= MDM2AP_ERRFATAL,
+		.end	= MDM2AP_ERRFATAL,
+		.name	= "MDM2AP_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_ERRFATAL,
+		.end	= AP2MDM_ERRFATAL,
+		.name	= "AP2MDM_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= MDM2AP_STATUS,
+		.end	= MDM2AP_STATUS,
+		.name	= "MDM2AP_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_STATUS,
+		.end	= AP2MDM_STATUS,
+		.name	= "AP2MDM_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_PMIC_RESET_N,
+		.end	= AP2MDM_PMIC_RESET_N,
+		.name	= "AP2MDM_PMIC_RESET_N",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_KPDPWR_N,
+		.end	= AP2MDM_KPDPWR_N,
+		.name	= "AP2MDM_KPDPWR_N",
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct mdm_platform_data mdm_platform_data = {
+	.mdm_version = "2.5",
+};
+
+static struct platform_device mdm_device = {
+	.name		= "mdm2_modem",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(mdm_resources),
+	.resource	= mdm_resources,
+	.dev		= {
+		.platform_data = &mdm_platform_data,
+	},
+};
+
+static struct platform_device *mdm_devices[] __initdata = {
+	&mdm_device,
+};
+
+#define MSM_SHARED_RAM_PHYS 0x80000000
+
+static void __init msm8960_map_io(void)
+{
+	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
+	msm_map_msm8960_io();
+
+	if (socinfo_init() < 0)
+		pr_err("socinfo_init() failed!\n");
+}
+
+static void __init msm8960_init_irq(void)
+{
+	unsigned int i;
+
+	msm_mpm_irq_extn_init();
+	gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
+						(void *)MSM_QGIC_CPU_BASE);
+
+	/* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
+	writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
+
+	writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
+	mb();
+
+	/* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
+	 * as they are configured as level, which does not play nice with
+	 * handle_percpu_irq.
+	 */
+	for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
+		if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
+			irq_set_handler(i, handle_percpu_irq);
+	}
+}
+
+static void __init msm8960_init_buses(void)
+{
+#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;
+#endif
+}
+
+static struct msm_spi_platform_data msm8960_qup_spi_gsbi1_pdata = {
+	.max_clock_speed = 15060000,
+};
+
+#ifdef CONFIG_USB_MSM_OTG_72K
+static struct msm_otg_platform_data msm_otg_pdata;
+#else
+#define USB_5V_EN		42
+static void msm_hsusb_vbus_power(bool on)
+{
+	int rc;
+	static bool vbus_is_on;
+	static struct regulator *mvs_otg_switch;
+
+	if (vbus_is_on == on)
+		return;
+
+	if (on) {
+		mvs_otg_switch = regulator_get(&msm8960_device_otg.dev,
+					       "vbus_otg");
+		if (IS_ERR(mvs_otg_switch)) {
+			pr_err("Unable to get mvs_otg_switch\n");
+			return;
+		}
+
+		rc = gpio_request(PM8921_GPIO_PM_TO_SYS(USB_5V_EN),
+						"usb_5v_en");
+		if (rc < 0) {
+			pr_err("failed to request usb_5v_en gpio\n");
+			goto put_mvs_otg;
+		}
+
+		rc = gpio_direction_output(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 1);
+		if (rc) {
+			pr_err("%s: unable to set_direction for gpio [%d]\n",
+				__func__, PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
+			goto free_usb_5v_en;
+		}
+
+		if (regulator_enable(mvs_otg_switch)) {
+			pr_err("unable to enable mvs_otg_switch\n");
+			goto err_ldo_gpio_set_dir;
+		}
+
+		vbus_is_on = true;
+		return;
+	}
+	regulator_disable(mvs_otg_switch);
+err_ldo_gpio_set_dir:
+	gpio_set_value(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
+free_usb_5v_en:
+	gpio_free(PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
+put_mvs_otg:
+	regulator_put(mvs_otg_switch);
+	vbus_is_on = false;
+}
+
+static int wr_phy_init_seq[] = {
+	0x44, 0x80, /* set VBUS valid threshold
+			and disconnect valid threshold */
+	0x38, 0x81, /* update DC voltage level */
+	0x14, 0x82, /* set preemphasis and rise/fall time */
+	0x13, 0x83, /* set source impedance adjusment */
+	-1};
+
+static int liquid_v1_phy_init_seq[] = {
+	0x44, 0x80,/* set VBUS valid threshold
+			and disconnect valid threshold */
+	0x3C, 0x81,/* update DC voltage level */
+	0x18, 0x82,/* set preemphasis and rise/fall time */
+	0x23, 0x83,/* set source impedance sdjusment */
+	-1};
+
+static struct msm_otg_platform_data msm_otg_pdata = {
+	.mode			= USB_OTG,
+	.otg_control		= OTG_PMIC_CONTROL,
+	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
+	.pclk_src_name		= "dfab_usb_hs_clk",
+	.pmic_id_irq		= PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
+	.vbus_power		= msm_hsusb_vbus_power,
+	.power_budget		= 750,
+};
+#endif
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+#define HSIC_HUB_RESET_GPIO	91
+static struct msm_hsic_host_platform_data msm_hsic_pdata = {
+	.strobe		= 150,
+	.data		= 151,
+};
+#else
+static struct msm_hsic_host_platform_data msm_hsic_pdata;
+#endif
+
+#define PID_MAGIC_ID		0x71432909
+#define SERIAL_NUM_MAGIC_ID	0x61945374
+#define SERIAL_NUMBER_LENGTH	127
+#define DLOAD_USB_BASE_ADD	0x2A03F0C8
+
+struct magic_num_struct {
+	uint32_t pid;
+	uint32_t serial_num;
+};
+
+struct dload_struct {
+	uint32_t	reserved1;
+	uint32_t	reserved2;
+	uint32_t	reserved3;
+	uint16_t	reserved4;
+	uint16_t	pid;
+	char		serial_number[SERIAL_NUMBER_LENGTH];
+	uint16_t	reserved5;
+	struct magic_num_struct magic_struct;
+};
+
+static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
+{
+	struct dload_struct __iomem *dload = 0;
+
+	dload = ioremap(DLOAD_USB_BASE_ADD, sizeof(*dload));
+	if (!dload) {
+		pr_err("%s: cannot remap I/O memory region: %08x\n",
+					__func__, DLOAD_USB_BASE_ADD);
+		return -ENXIO;
+	}
+
+	pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
+				__func__, dload, pid, snum);
+	/* update pid */
+	dload->magic_struct.pid = PID_MAGIC_ID;
+	dload->pid = pid;
+
+	/* update serial number */
+	dload->magic_struct.serial_num = 0;
+	if (!snum) {
+		memset(dload->serial_number, 0, SERIAL_NUMBER_LENGTH);
+		goto out;
+	}
+
+	dload->magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
+	strlcpy(dload->serial_number, snum, SERIAL_NUMBER_LENGTH);
+out:
+	iounmap(dload);
+	return 0;
+}
+
+static struct android_usb_platform_data android_usb_pdata = {
+	.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
+};
+
+static struct platform_device android_usb_device = {
+	.name	= "android_usb",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &android_usb_pdata,
+	},
+};
+
+static uint8_t spm_wfi_cmd_sequence[] __initdata = {
+			0x03, 0x0f,
+};
+
+static uint8_t spm_power_collapse_without_rpm[] __initdata = {
+			0x00, 0x24, 0x54, 0x10,
+			0x09, 0x03, 0x01,
+			0x10, 0x54, 0x30, 0x0C,
+			0x24, 0x30, 0x0f,
+};
+
+static uint8_t spm_power_collapse_with_rpm[] __initdata = {
+			0x00, 0x24, 0x54, 0x10,
+			0x09, 0x07, 0x01, 0x0B,
+			0x10, 0x54, 0x30, 0x0C,
+			0x24, 0x30, 0x0f,
+};
+
+static struct msm_spm_seq_entry msm_spm_seq_list[] __initdata = {
+	[0] = {
+		.mode = MSM_SPM_MODE_CLOCK_GATING,
+		.notify_rpm = false,
+		.cmd = spm_wfi_cmd_sequence,
+	},
+	[1] = {
+		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
+		.notify_rpm = false,
+		.cmd = spm_power_collapse_without_rpm,
+	},
+	[2] = {
+		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
+		.notify_rpm = true,
+		.cmd = spm_power_collapse_with_rpm,
+	},
+};
+
+static struct msm_spm_platform_data msm_spm_data[] __initdata = {
+	[0] = {
+		.reg_base_addr = MSM_SAW0_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
+		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
+#if defined(CONFIG_MSM_AVS_HW)
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
+#endif
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.vctl_timeout_us = 50,
+		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
+		.modes = msm_spm_seq_list,
+	},
+	[1] = {
+		.reg_base_addr = MSM_SAW1_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
+		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
+#if defined(CONFIG_MSM_AVS_HW)
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
+#endif
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
+		.vctl_timeout_us = 50,
+		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
+		.modes = msm_spm_seq_list,
+	},
+};
+
+static uint8_t l2_spm_wfi_cmd_sequence[] __initdata = {
+			0x00, 0x20, 0x03, 0x20,
+			0x00, 0x0f,
+};
+
+static uint8_t l2_spm_gdhs_cmd_sequence[] __initdata = {
+			0x00, 0x20, 0x34, 0x64,
+			0x48, 0x07, 0x48, 0x20,
+			0x50, 0x64, 0x04, 0x34,
+			0x50, 0x0f,
+};
+static uint8_t l2_spm_power_off_cmd_sequence[] __initdata = {
+			0x00, 0x10, 0x34, 0x64,
+			0x48, 0x07, 0x48, 0x10,
+			0x50, 0x64, 0x04, 0x34,
+			0x50, 0x0F,
+};
+
+static struct msm_spm_seq_entry msm_spm_l2_seq_list[] __initdata = {
+	[0] = {
+		.mode = MSM_SPM_L2_MODE_RETENTION,
+		.notify_rpm = false,
+		.cmd = l2_spm_wfi_cmd_sequence,
+	},
+	[1] = {
+		.mode = MSM_SPM_L2_MODE_GDHS,
+		.notify_rpm = true,
+		.cmd = l2_spm_gdhs_cmd_sequence,
+	},
+	[2] = {
+		.mode = MSM_SPM_L2_MODE_POWER_COLLAPSE,
+		.notify_rpm = true,
+		.cmd = l2_spm_power_off_cmd_sequence,
+	},
+};
+
+static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
+	[0] = {
+		.reg_base_addr = MSM_SAW_L2_BASE,
+		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
+		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A00020,
+		.modes = msm_spm_l2_seq_list,
+		.num_modes = ARRAY_SIZE(msm_spm_l2_seq_list),
+	},
+};
+
+#define PM_HAP_EN_GPIO		PM8921_GPIO_PM_TO_SYS(33)
+#define PM_HAP_LEN_GPIO		PM8921_GPIO_PM_TO_SYS(20)
+
+static struct msm_xo_voter *xo_handle_d1;
+
+static int isa1200_power(int on)
+{
+	int rc = 0;
+
+	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, !!on);
+
+	rc = on ? msm_xo_mode_vote(xo_handle_d1, MSM_XO_MODE_ON) :
+			msm_xo_mode_vote(xo_handle_d1, MSM_XO_MODE_OFF);
+	if (rc < 0) {
+		pr_err("%s: failed to %svote for TCXO D1 buffer%d\n",
+				__func__, on ? "" : "de-", rc);
+		goto err_xo_vote;
+	}
+
+	return 0;
+
+err_xo_vote:
+	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, !on);
+	return rc;
+}
+
+static int isa1200_dev_setup(bool enable)
+{
+	int rc = 0;
+
+	struct pm_gpio hap_gpio_config = {
+		.direction      = PM_GPIO_DIR_OUT,
+		.pull           = PM_GPIO_PULL_NO,
+		.out_strength   = PM_GPIO_STRENGTH_HIGH,
+		.function       = PM_GPIO_FUNC_NORMAL,
+		.inv_int_pol    = 0,
+		.vin_sel        = 2,
+		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+		.output_value   = 0,
+	};
+
+	if (enable == true) {
+		rc = pm8xxx_gpio_config(PM_HAP_EN_GPIO, &hap_gpio_config);
+		if (rc) {
+			pr_err("%s: pm8921 gpio %d config failed(%d)\n",
+					__func__, PM_HAP_EN_GPIO, rc);
+			return rc;
+		}
+
+		rc = pm8xxx_gpio_config(PM_HAP_LEN_GPIO, &hap_gpio_config);
+		if (rc) {
+			pr_err("%s: pm8921 gpio %d config failed(%d)\n",
+					__func__, PM_HAP_LEN_GPIO, rc);
+			return rc;
+		}
+
+		rc = gpio_request(HAP_SHIFT_LVL_OE_GPIO, "hap_shft_lvl_oe");
+		if (rc) {
+			pr_err("%s: unable to request gpio %d (%d)\n",
+					__func__, HAP_SHIFT_LVL_OE_GPIO, rc);
+			return rc;
+		}
+
+		rc = gpio_direction_output(HAP_SHIFT_LVL_OE_GPIO, 0);
+		if (rc) {
+			pr_err("%s: Unable to set direction\n", __func__);
+			goto free_gpio;
+		}
+
+		xo_handle_d1 = msm_xo_get(MSM_XO_TCXO_D1, "isa1200");
+		if (IS_ERR(xo_handle_d1)) {
+			rc = PTR_ERR(xo_handle_d1);
+			pr_err("%s: failed to get the handle for D1(%d)\n",
+							__func__, rc);
+			goto gpio_set_dir;
+		}
+	} else {
+		gpio_free(HAP_SHIFT_LVL_OE_GPIO);
+
+		msm_xo_put(xo_handle_d1);
+	}
+
+	return 0;
+
+gpio_set_dir:
+	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, 0);
+free_gpio:
+	gpio_free(HAP_SHIFT_LVL_OE_GPIO);
+	return rc;
+}
+
+static struct isa1200_regulator isa1200_reg_data[] = {
+	{
+		.name = "vcc_i2c",
+		.min_uV = ISA_I2C_VTG_MIN_UV,
+		.max_uV = ISA_I2C_VTG_MAX_UV,
+		.load_uA = ISA_I2C_CURR_UA,
+	},
+};
+
+static struct isa1200_platform_data isa1200_1_pdata = {
+	.name = "vibrator",
+	.dev_setup = isa1200_dev_setup,
+	.power_on = isa1200_power,
+	.hap_en_gpio = PM_HAP_EN_GPIO,
+	.hap_len_gpio = PM_HAP_LEN_GPIO,
+	.max_timeout = 15000,
+	.mode_ctrl = PWM_GEN_MODE,
+	.pwm_fd = {
+		.pwm_div = 256,
+	},
+	.is_erm = false,
+	.smart_en = true,
+	.ext_clk_en = true,
+	.chip_en = 1,
+	.regulator_info = isa1200_reg_data,
+	.num_regulators = ARRAY_SIZE(isa1200_reg_data),
+};
+
+static struct i2c_board_info msm_isa1200_board_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("isa1200_1", 0x90>>1),
+		.platform_data = &isa1200_1_pdata,
+	},
+};
+
+#define CYTTSP_TS_GPIO_IRQ		11
+#define CYTTSP_TS_SLEEP_GPIO		50
+#define CYTTSP_TS_RESOUT_N_GPIO		52
+
+/*virtual key support */
+static ssize_t tma340_vkeys_show(struct kobject *kobj,
+			struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, 200,
+	__stringify(EV_KEY) ":" __stringify(KEY_BACK) ":73:1120:97:97"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":230:1120:97:97"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":389:1120:97:97"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":544:1120:97:97"
+	"\n");
+}
+
+static struct kobj_attribute tma340_vkeys_attr = {
+	.attr = {
+		.mode = S_IRUGO,
+	},
+	.show = &tma340_vkeys_show,
+};
+
+static struct attribute *tma340_properties_attrs[] = {
+	&tma340_vkeys_attr.attr,
+	NULL
+};
+
+static struct attribute_group tma340_properties_attr_group = {
+	.attrs = tma340_properties_attrs,
+};
+
+
+static int cyttsp_platform_init(struct i2c_client *client)
+{
+	int rc = 0;
+	static struct kobject *tma340_properties_kobj;
+
+	tma340_vkeys_attr.attr.name = "virtualkeys.cyttsp-i2c";
+	tma340_properties_kobj = kobject_create_and_add("board_properties",
+								NULL);
+	if (tma340_properties_kobj)
+		rc = sysfs_create_group(tma340_properties_kobj,
+					&tma340_properties_attr_group);
+	if (!tma340_properties_kobj || rc)
+		pr_err("%s: failed to create board_properties\n",
+				__func__);
+
+	return 0;
+}
+
+static struct cyttsp_regulator regulator_data[] = {
+	{
+		.name = "vdd",
+		.min_uV = CY_TMA300_VTG_MIN_UV,
+		.max_uV = CY_TMA300_VTG_MAX_UV,
+		.hpm_load_uA = CY_TMA300_CURR_24HZ_UA,
+		.lpm_load_uA = CY_TMA300_SLEEP_CURR_UA,
+	},
+	/* TODO: Remove after runtime PM is enabled in I2C driver */
+	{
+		.name = "vcc_i2c",
+		.min_uV = CY_I2C_VTG_MIN_UV,
+		.max_uV = CY_I2C_VTG_MAX_UV,
+		.hpm_load_uA = CY_I2C_CURR_UA,
+		.lpm_load_uA = CY_I2C_SLEEP_CURR_UA,
+	},
+};
+
+static struct cyttsp_platform_data cyttsp_pdata = {
+	.panel_maxx = 634,
+	.panel_maxy = 1166,
+	.disp_maxx = 616,
+	.disp_maxy = 1023,
+	.disp_minx = 0,
+	.disp_miny = 16,
+	.flags = 0x01,
+	.gen = CY_GEN3,	/* or */
+	.use_st = CY_USE_ST,
+	.use_mt = CY_USE_MT,
+	.use_hndshk = CY_SEND_HNDSHK,
+	.use_trk_id = CY_USE_TRACKING_ID,
+	.use_sleep = CY_USE_DEEP_SLEEP_SEL | CY_USE_LOW_POWER_SEL,
+	.use_gestures = CY_USE_GESTURES,
+	.fw_fname = "cyttsp_8960_cdp.hex",
+	/* activate up to 4 groups
+	 * and set active distance
+	 */
+	.gest_set = CY_GEST_GRP1 | CY_GEST_GRP2 |
+				CY_GEST_GRP3 | CY_GEST_GRP4 |
+				CY_ACT_DIST,
+	/* change act_intrvl to customize the Active power state
+	 * scanning/processing refresh interval for Operating mode
+	 */
+	.act_intrvl = CY_ACT_INTRVL_DFLT,
+	/* change tch_tmout to customize the touch timeout for the
+	 * Active power state for Operating mode
+	 */
+	.tch_tmout = CY_TCH_TMOUT_DFLT,
+	/* change lp_intrvl to customize the Low Power power state
+	 * scanning/processing refresh interval for Operating mode
+	 */
+	.lp_intrvl = CY_LP_INTRVL_DFLT,
+	.sleep_gpio = CYTTSP_TS_SLEEP_GPIO,
+	.resout_gpio = CYTTSP_TS_RESOUT_N_GPIO,
+	.irq_gpio = CYTTSP_TS_GPIO_IRQ,
+	.regulator_info = regulator_data,
+	.num_regulators = ARRAY_SIZE(regulator_data),
+	.init = cyttsp_platform_init,
+	.correct_fw_ver = 9,
+};
+
+static struct i2c_board_info cyttsp_info[] __initdata = {
+	{
+		I2C_BOARD_INFO(CY_I2C_NAME, 0x24),
+		.platform_data = &cyttsp_pdata,
+#ifndef CY_USE_TIMER
+		.irq = MSM_GPIO_TO_INT(CYTTSP_TS_GPIO_IRQ),
+#endif /* CY_USE_TIMER */
+	},
+};
+
+/* configuration data */
+static const u8 mxt_config_data[] = {
+	/* T6 Object */
+	0, 0, 0, 0, 0, 0,
+	/* T38 Object */
+	11, 2, 0, 11, 11, 11, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0,
+	/* T7 Object */
+	100, 16, 50,
+	/* T8 Object */
+	8, 0, 0, 0, 0, 0, 8, 14, 50, 215,
+	/* T9 Object */
+	131, 0, 0, 26, 42, 0, 32, 63, 3, 5,
+	0, 2, 1, 113, 10, 10, 8, 10, 255, 2,
+	85, 5, 0, 0, 20, 20, 75, 25, 202, 29,
+	10, 10, 45, 46,
+	/* T15 Object */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0,
+	/* T22 Object */
+	5, 0, 0, 0, 0, 0, 0, 0, 30, 0,
+	0, 0, 5, 8, 10, 13, 0,
+	/* T24 Object */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* T25 Object */
+	3, 0, 188, 52, 52, 33, 0, 0, 0, 0,
+	0, 0, 0, 0,
+	/* T27 Object */
+	0, 0, 0, 0, 0, 0, 0,
+	/* T28 Object */
+	0, 0, 0, 8, 12, 60,
+	/* T40 Object */
+	0, 0, 0, 0, 0,
+	/* T41 Object */
+	0, 0, 0, 0, 0, 0,
+	/* T43 Object */
+	0, 0, 0, 0, 0, 0,
+};
+
+#define MXT_TS_GPIO_IRQ		11
+#define MXT_TS_LDO_EN_GPIO	50
+#define MXT_TS_RESET_GPIO	52
+
+static void mxt_init_hw_liquid(void)
+{
+	int rc;
+
+	rc = gpio_request(MXT_TS_GPIO_IRQ, "mxt_ts_irq_gpio");
+	if (rc) {
+		pr_err("%s: unable to request mxt_ts_irq gpio [%d]\n",
+				__func__, MXT_TS_GPIO_IRQ);
+		return;
+	}
+
+	rc = gpio_direction_input(MXT_TS_GPIO_IRQ);
+	if (rc) {
+		pr_err("%s: unable to set_direction for mxt_ts_irq gpio [%d]\n",
+				__func__, MXT_TS_GPIO_IRQ);
+		goto err_irq_gpio_req;
+	}
+
+	rc = gpio_request(MXT_TS_LDO_EN_GPIO, "mxt_ldo_en_gpio");
+	if (rc) {
+		pr_err("%s: unable to request mxt_ldo_en gpio [%d]\n",
+				__func__, MXT_TS_LDO_EN_GPIO);
+		goto err_irq_gpio_req;
+	}
+
+	rc = gpio_direction_output(MXT_TS_LDO_EN_GPIO, 1);
+	if (rc) {
+		pr_err("%s: unable to set_direction for mxt_ldo_en gpio [%d]\n",
+				__func__, MXT_TS_LDO_EN_GPIO);
+		goto err_ldo_gpio_req;
+	}
+
+	rc = gpio_request(MXT_TS_RESET_GPIO, "mxt_reset_gpio");
+	if (rc) {
+		pr_err("%s: unable to request mxt_reset gpio [%d]\n",
+				__func__, MXT_TS_RESET_GPIO);
+		goto err_ldo_gpio_set_dir;
+	}
+
+	rc = gpio_direction_output(MXT_TS_RESET_GPIO, 1);
+	if (rc) {
+		pr_err("%s: unable to set_direction for mxt_reset gpio [%d]\n",
+				__func__, MXT_TS_RESET_GPIO);
+		goto err_reset_gpio_req;
+	}
+
+	return;
+
+err_reset_gpio_req:
+	gpio_free(MXT_TS_RESET_GPIO);
+err_ldo_gpio_set_dir:
+	gpio_set_value(MXT_TS_LDO_EN_GPIO, 0);
+err_ldo_gpio_req:
+	gpio_free(MXT_TS_LDO_EN_GPIO);
+err_irq_gpio_req:
+	gpio_free(MXT_TS_GPIO_IRQ);
+}
+
+static struct mxt_platform_data mxt_platform_data = {
+	.config			= mxt_config_data,
+	.config_length		= ARRAY_SIZE(mxt_config_data),
+	.x_size			= 1365,
+	.y_size			= 767,
+	.irqflags		= IRQF_TRIGGER_FALLING,
+	.i2c_pull_up		= true,
+};
+
+static struct i2c_board_info mxt_device_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("atmel_mxt_ts", 0x5b),
+		.platform_data = &mxt_platform_data,
+		.irq = MSM_GPIO_TO_INT(MXT_TS_GPIO_IRQ),
+	},
+};
+
+static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
+{
+}
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi4_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi3_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi10_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi12_pdata = {
+	.clk_freq = 100000,
+	.src_clk_rate = 24000000,
+	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+};
+
+static struct msm_rpm_platform_data msm_rpm_data = {
+	.reg_base_addrs = {
+		[MSM_RPM_PAGE_STATUS] = MSM_RPM_BASE,
+		[MSM_RPM_PAGE_CTRL] = MSM_RPM_BASE + 0x400,
+		[MSM_RPM_PAGE_REQ] = MSM_RPM_BASE + 0x600,
+		[MSM_RPM_PAGE_ACK] = MSM_RPM_BASE + 0xa00,
+	},
+
+	.irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
+	.irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
+	.irq_vmpm = RPM_APCC_CPU0_GP_MEDIUM_IRQ,
+	.msm_apps_ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
+	.msm_apps_ipc_rpm_val = 4,
+};
+
+static struct ks8851_pdata spi_eth_pdata = {
+	.irq_gpio = KS8851_IRQ_GPIO,
+	.rst_gpio = KS8851_RST_GPIO,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+	{
+		.modalias               = "ks8851",
+		.irq                    = MSM_GPIO_TO_INT(KS8851_IRQ_GPIO),
+		.max_speed_hz           = 19200000,
+		.bus_num                = 0,
+		.chip_select            = 0,
+		.mode                   = SPI_MODE_0,
+		.platform_data		= &spi_eth_pdata
+	},
+	{
+		.modalias               = "dsi_novatek_3d_panel_spi",
+		.max_speed_hz           = 10800000,
+		.bus_num                = 0,
+		.chip_select            = 1,
+		.mode                   = SPI_MODE_0,
+	},
+};
+
+static struct platform_device msm_device_saw_core0 = {
+	.name          = "saw-regulator",
+	.id            = 0,
+	.dev	= {
+		.platform_data = &msm_saw_regulator_pdata_s5,
+	},
+};
+
+static struct platform_device msm_device_saw_core1 = {
+	.name          = "saw-regulator",
+	.id            = 1,
+	.dev	= {
+		.platform_data = &msm_saw_regulator_pdata_s6,
+	},
+};
+
+static struct tsens_platform_data msm_tsens_pdata  = {
+		.slope			= 910,
+		.tsens_factor		= 1000,
+		.hw_type		= MSM_8960,
+		.tsens_num_sensor	= 5,
+};
+
+static struct platform_device msm_tsens_device = {
+	.name	= "tsens8960-tm",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &msm_tsens_pdata,
+	},
+};
+
+#ifdef CONFIG_MSM_FAKE_BATTERY
+static struct platform_device fish_battery_device = {
+	.name = "fish_battery",
+};
+#endif
+
+static struct platform_device msm8960_device_ext_5v_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= PM8921_MPP_PM_TO_SYS(7),
+	.dev	= {
+		.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
+	},
+};
+
+static struct platform_device msm8960_device_ext_l2_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= 91,
+	.dev	= {
+		.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_L2],
+	},
+};
+
+static struct platform_device msm8960_device_ext_3p3v_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= PM8921_GPIO_PM_TO_SYS(17),
+	.dev	= {
+		.platform_data =
+			&msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_3P3V],
+	},
+};
+
+static struct platform_device msm8960_device_rpm_regulator __devinitdata = {
+	.name	= "rpm-regulator",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &msm_rpm_regulator_pdata,
+	},
+};
+
+static struct msm_rpm_log_platform_data msm_rpm_log_pdata = {
+	.phys_addr_base = 0x0010C000,
+	.reg_offsets = {
+		[MSM_RPM_LOG_PAGE_INDICES] = 0x00000080,
+		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
+	},
+	.phys_size = SZ_8K,
+	.log_len = 4096,		  /* log's buffer length in bytes */
+	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+};
+
+static struct platform_device msm_rpm_log_device = {
+	.name	= "msm_rpm_log",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &msm_rpm_log_pdata,
+	},
+};
+
+static struct platform_device *common_devices[] __initdata = {
+	&msm8960_device_dmov,
+	&msm_device_smd,
+	&msm8960_device_uart_gsbi5,
+	&msm_device_uart_dm6,
+	&msm_device_saw_core0,
+	&msm_device_saw_core1,
+	&msm8960_device_ext_5v_vreg,
+	&msm8960_device_ext_l2_vreg,
+	&msm8960_device_ssbi_pm8921,
+	&msm8960_device_qup_spi_gsbi1,
+	&msm8960_device_qup_i2c_gsbi3,
+	&msm8960_device_qup_i2c_gsbi4,
+	&msm8960_device_qup_i2c_gsbi10,
+#ifndef CONFIG_MSM_DSPS
+	&msm8960_device_qup_i2c_gsbi12,
+#endif
+	&msm_slim_ctrl,
+	&msm_device_wcnss_wlan,
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+	&qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+	&qcedev_device,
+#endif
+#ifdef CONFIG_MSM_ROTATOR
+	&msm_rotator_device,
+#endif
+	&msm_device_sps,
+#ifdef CONFIG_MSM_FAKE_BATTERY
+	&fish_battery_device,
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	&android_pmem_device,
+	&android_pmem_adsp_device,
+#endif
+	&android_pmem_audio_device,
+#endif
+	&msm_device_vidc,
+	&msm_device_bam_dmux,
+	&msm_fm_platform_init,
+
+#ifdef CONFIG_HW_RANDOM_MSM
+	&msm_device_rng,
+#endif
+	&msm_rpm_device,
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
+	&msm_rpm_log_device,
+	&msm_rpm_stat_device,
+	&msm_device_tz_log,
+
+#ifdef CONFIG_MSM_QDSS
+	&msm_etb_device,
+	&msm_tpiu_device,
+	&msm_funnel_device,
+	&msm_debug_device,
+	&msm_ptm_device,
+#endif
+	&msm_device_dspcrashd_8960,
+	&msm8960_device_watchdog,
+};
+
+static struct platform_device *sim_devices[] __initdata = {
+	&msm8960_device_otg,
+	&msm8960_device_gadget_peripheral,
+	&msm_device_hsusb_host,
+	&msm_device_hsic_host,
+	&android_usb_device,
+	&msm_device_vidc,
+	&msm_bus_apps_fabric,
+	&msm_bus_sys_fabric,
+	&msm_bus_mm_fabric,
+	&msm_bus_sys_fpb,
+	&msm_bus_cpss_fpb,
+	&msm_pcm,
+	&msm_pcm_routing,
+	&msm_cpudai0,
+	&msm_cpudai1,
+	&msm_cpudai_hdmi_rx,
+	&msm_cpudai_bt_rx,
+	&msm_cpudai_bt_tx,
+	&msm_cpudai_fm_rx,
+	&msm_cpudai_fm_tx,
+	&msm_cpudai_auxpcm_rx,
+	&msm_cpudai_auxpcm_tx,
+	&msm_cpu_fe,
+	&msm_stub_codec,
+	&msm_voice,
+	&msm_voip,
+	&msm_lpa_pcm,
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+	&qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+	&qcedev_device,
+#endif
+};
+
+static struct platform_device *rumi3_devices[] __initdata = {
+	&msm_kgsl_3d0,
+	&msm_kgsl_2d0,
+	&msm_kgsl_2d1,
+#ifdef CONFIG_MSM_GEMINI
+	&msm8960_gemini_device,
+#endif
+};
+
+static struct platform_device *cdp_devices[] __initdata = {
+	&msm_8960_q6_lpass,
+	&msm_8960_q6_mss_fw,
+	&msm_8960_q6_mss_sw,
+	&msm8960_device_otg,
+	&msm8960_device_gadget_peripheral,
+	&msm_device_hsusb_host,
+	&android_usb_device,
+	&msm_pcm,
+	&msm_pcm_routing,
+	&msm_cpudai0,
+	&msm_cpudai1,
+	&msm_cpudai_hdmi_rx,
+	&msm_cpudai_bt_rx,
+	&msm_cpudai_bt_tx,
+	&msm_cpudai_fm_rx,
+	&msm_cpudai_fm_tx,
+	&msm_cpudai_auxpcm_rx,
+	&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
+	&msm_voice,
+	&msm_voip,
+	&msm_lpa_pcm,
+	&msm_cpudai_afe_01_rx,
+	&msm_cpudai_afe_01_tx,
+	&msm_cpudai_afe_02_rx,
+	&msm_cpudai_afe_02_tx,
+	&msm_pcm_afe,
+	&msm_pcm_hostless,
+	&msm_bus_apps_fabric,
+	&msm_bus_sys_fabric,
+	&msm_bus_mm_fabric,
+	&msm_bus_sys_fpb,
+	&msm_bus_cpss_fpb,
+	&msm_tsens_device,
+};
+
+static void __init msm8960_i2c_init(void)
+{
+	msm8960_device_qup_i2c_gsbi4.dev.platform_data =
+					&msm8960_i2c_qup_gsbi4_pdata;
+
+	msm8960_device_qup_i2c_gsbi3.dev.platform_data =
+					&msm8960_i2c_qup_gsbi3_pdata;
+
+	msm8960_device_qup_i2c_gsbi10.dev.platform_data =
+					&msm8960_i2c_qup_gsbi10_pdata;
+
+	msm8960_device_qup_i2c_gsbi12.dev.platform_data =
+					&msm8960_i2c_qup_gsbi12_pdata;
+}
+
+static void __init msm8960_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},
+
+	{0, 1, "C1", "STANDALONE_POWER_COLLAPSE",
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
+
+	{0, 2, "C2", "POWER_COLLAPSE",
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE},
+
+	{1, 0, "C0", "WFI",
+		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
+
+	{1, 1, "C1", "STANDALONE_POWER_COLLAPSE",
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
+};
+
+static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR * 2] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 1,
+		.suspend_enabled = 1,
+	},
+
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
+		.idle_supported = 0,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
+		.idle_supported = 1,
+		.suspend_supported = 1,
+		.idle_enabled = 0,
+		.suspend_enabled = 0,
+	},
+
+	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
+		.idle_supported = 1,
+		.suspend_supported = 0,
+		.idle_enabled = 1,
+		.suspend_enabled = 0,
+	},
+};
+
+static struct msm_rpmrs_level msm_rpmrs_levels[] __initdata = {
+	{
+		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT,
+		MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
+		true,
+		100, 8000, 100000, 1,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
+		MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
+		true,
+		2000, 6000, 60100000, 3000,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(ON, GDHS, MAX, ACTIVE),
+		false,
+		4200, 5000, 60350000, 3500,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(ON, HSFS_OPEN, MAX, ACTIVE),
+		false,
+		6300, 4500, 65350000, 4800,
+	},
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(ON, HSFS_OPEN, ACTIVE, RET_HIGH),
+		false,
+		7000, 3500, 66600000, 5150,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, GDHS, MAX, ACTIVE),
+		false,
+		11700, 2500, 67850000, 5500,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, MAX, ACTIVE),
+		false,
+		13800, 2000, 71850000, 6800,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, ACTIVE, RET_HIGH),
+		false,
+		29700, 500, 75850000, 8800,
+	},
+
+	{
+		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
+		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, RET_HIGH, RET_LOW),
+		false,
+		29700, 0, 76350000, 9800,
+	},
+};
+
+#ifdef CONFIG_I2C
+#define I2C_SURF 1
+#define I2C_FFA  (1 << 1)
+#define I2C_RUMI (1 << 2)
+#define I2C_SIM  (1 << 3)
+#define I2C_FLUID (1 << 4)
+#define I2C_LIQUID (1 << 5)
+
+struct i2c_registry {
+	u8                     machs;
+	int                    bus;
+	struct i2c_board_info *info;
+	int                    len;
+};
+
+#ifdef CONFIG_MSM_CAMERA
+static struct i2c_board_info msm_camera_boardinfo[] __initdata = {
+#ifdef CONFIG_IMX074
+	{
+	I2C_BOARD_INFO("imx074", 0x1A),
+	},
+#endif
+#ifdef CONFIG_OV2720
+	{
+	I2C_BOARD_INFO("ov2720", 0x6C),
+	},
+#endif
+#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
+	{
+	I2C_BOARD_INFO("sc628a", 0x6E),
+	},
+#endif
+};
+#endif
+
+/* Sensors DSPS platform data */
+#ifdef CONFIG_MSM_DSPS
+#define DSPS_PIL_GENERIC_NAME		"dsps"
+#endif /* CONFIG_MSM_DSPS */
+
+static void __init msm8960_init_dsps(void)
+{
+#ifdef CONFIG_MSM_DSPS
+	struct msm_dsps_platform_data *pdata =
+		msm_dsps_device.dev.platform_data;
+	pdata->pil_name = DSPS_PIL_GENERIC_NAME;
+	pdata->gpios = NULL;
+	pdata->gpios_num = 0;
+
+	platform_device_register(&msm_dsps_device);
+#endif /* CONFIG_MSM_DSPS */
+}
+
+static void __init msm8960_init_hsic(void)
+{
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+	uint32_t version = socinfo_get_version();
+
+	if (SOCINFO_VERSION_MAJOR(version) == 1)
+		return;
+
+	if (PLATFORM_IS_CHARM25() || machine_is_msm8960_liquid())
+		platform_device_register(&msm_device_hsic_host);
+#endif
+}
+
+#ifdef CONFIG_ISL9519_CHARGER
+static struct isl_platform_data isl_data __initdata = {
+	.valid_n_gpio		= 0,	/* Not required when notify-by-pmic */
+	.chg_detection_config	= NULL,	/* Not required when notify-by-pmic */
+	.max_system_voltage	= 4200,
+	.min_system_voltage	= 3200,
+	.chgcurrent		= 1000, /* 1900, */
+	.term_current		= 400,	/* Need fine tuning */
+	.input_current		= 2048,
+};
+
+static struct i2c_board_info isl_charger_i2c_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("isl9519q", 0x9),
+		.irq		= 0,	/* Not required when notify-by-pmic */
+		.platform_data	= &isl_data,
+	},
+};
+#endif /* CONFIG_ISL9519_CHARGER */
+
+static struct i2c_registry msm8960_i2c_devices[] __initdata = {
+#ifdef CONFIG_MSM_CAMERA
+	{
+		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI,
+		MSM_8960_GSBI4_QUP_I2C_BUS_ID,
+		msm_camera_boardinfo,
+		ARRAY_SIZE(msm_camera_boardinfo),
+	},
+#endif
+#ifdef CONFIG_ISL9519_CHARGER
+	{
+		I2C_LIQUID,
+		MSM_8960_GSBI10_QUP_I2C_BUS_ID,
+		isl_charger_i2c_info,
+		ARRAY_SIZE(isl_charger_i2c_info),
+	},
+#endif /* CONFIG_ISL9519_CHARGER */
+	{
+		I2C_SURF | I2C_FFA | I2C_FLUID,
+		MSM_8960_GSBI3_QUP_I2C_BUS_ID,
+		cyttsp_info,
+		ARRAY_SIZE(cyttsp_info),
+	},
+	{
+		I2C_LIQUID,
+		MSM_8960_GSBI3_QUP_I2C_BUS_ID,
+		mxt_device_info,
+		ARRAY_SIZE(mxt_device_info),
+	},
+	{
+		I2C_LIQUID,
+		MSM_8960_GSBI10_QUP_I2C_BUS_ID,
+		msm_isa1200_board_info,
+		ARRAY_SIZE(msm_isa1200_board_info),
+	},
+};
+#endif /* CONFIG_I2C */
+
+static void __init register_i2c_devices(void)
+{
+#ifdef CONFIG_I2C
+	u8 mach_mask = 0;
+	int i;
+
+	/* Build the matching 'supported_machs' bitmask */
+	if (machine_is_msm8960_cdp())
+		mach_mask = I2C_SURF;
+	else if (machine_is_msm8960_rumi3())
+		mach_mask = I2C_RUMI;
+	else if (machine_is_msm8960_sim())
+		mach_mask = I2C_SIM;
+	else if (machine_is_msm8960_fluid())
+		mach_mask = I2C_FLUID;
+	else if (machine_is_msm8960_liquid())
+		mach_mask = I2C_LIQUID;
+	else if (machine_is_msm8960_mtp())
+		mach_mask = I2C_FFA;
+	else
+		pr_err("unmatched machine ID in register_i2c_devices\n");
+
+	/* Run the array and install devices as appropriate */
+	for (i = 0; i < ARRAY_SIZE(msm8960_i2c_devices); ++i) {
+		if (msm8960_i2c_devices[i].machs & mach_mask)
+			i2c_register_board_info(msm8960_i2c_devices[i].bus,
+						msm8960_i2c_devices[i].info,
+						msm8960_i2c_devices[i].len);
+	}
+#endif
+}
+
+static void __init msm8960_sim_init(void)
+{
+	struct msm_watchdog_pdata *wdog_pdata = (struct msm_watchdog_pdata *)
+		&msm8960_device_watchdog.dev.platform_data;
+
+	wdog_pdata->bark_time = 15000;
+	BUG_ON(msm_rpm_init(&msm_rpm_data));
+	BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
+				ARRAY_SIZE(msm_rpmrs_levels)));
+	regulator_suppress_info_printing();
+	platform_device_register(&msm8960_device_rpm_regulator);
+	msm_clock_init(&msm8960_clock_init_data);
+	msm8960_init_pmic();
+
+	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
+	msm8960_init_gpiomux();
+	msm8960_i2c_init();
+	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+	msm_spm_l2_init(msm_spm_l2_data);
+	msm8960_init_buses();
+	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	msm8960_pm8921_gpio_mpp_init();
+	platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices));
+	acpuclk_init(&acpuclk_8960_soc_data);
+
+	msm8960_device_qup_spi_gsbi1.dev.platform_data =
+				&msm8960_qup_spi_gsbi1_pdata;
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+	msm8960_init_mmc();
+	msm8960_init_fb();
+	slim_register_board_info(msm_slim_devices,
+		ARRAY_SIZE(msm_slim_devices));
+	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
+	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
+	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
+				msm_pm_data);
+	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
+}
+
+static void __init msm8960_rumi3_init(void)
+{
+	BUG_ON(msm_rpm_init(&msm_rpm_data));
+	BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
+				ARRAY_SIZE(msm_rpmrs_levels)));
+	regulator_suppress_info_printing();
+	platform_device_register(&msm8960_device_rpm_regulator);
+	msm_clock_init(&msm8960_dummy_clock_init_data);
+	msm8960_init_gpiomux();
+	msm8960_init_pmic();
+	msm8960_device_qup_spi_gsbi1.dev.platform_data =
+				&msm8960_qup_spi_gsbi1_pdata;
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+	msm8960_i2c_init();
+	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+	msm_spm_l2_init(msm_spm_l2_data);
+	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	msm8960_pm8921_gpio_mpp_init();
+	platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
+	msm8960_init_mmc();
+	register_i2c_devices();
+	msm8960_init_fb();
+	slim_register_board_info(msm_slim_devices,
+		ARRAY_SIZE(msm_slim_devices));
+	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
+	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
+	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
+				msm_pm_data);
+	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
+}
+
+static void __init msm8960_cdp_init(void)
+{
+	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
+		pr_err("meminfo_init() failed!\n");
+
+	BUG_ON(msm_rpm_init(&msm_rpm_data));
+	BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
+				ARRAY_SIZE(msm_rpmrs_levels)));
+
+	regulator_suppress_info_printing();
+	if (msm_xo_init())
+		pr_err("Failed to initialize XO votes\n");
+	platform_device_register(&msm8960_device_rpm_regulator);
+	msm_clock_init(&msm8960_clock_init_data);
+	if (machine_is_msm8960_liquid())
+		msm_otg_pdata.mhl_enable = true;
+	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
+	if (machine_is_msm8960_mtp() || machine_is_msm8960_fluid() ||
+		machine_is_msm8960_cdp()) {
+		msm_otg_pdata.phy_init_seq = wr_phy_init_seq;
+	} else if (machine_is_msm8960_liquid()) {
+			msm_otg_pdata.phy_init_seq =
+				liquid_v1_phy_init_seq;
+	}
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+	if (machine_is_msm8960_liquid()) {
+		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
+			msm_hsic_pdata.hub_reset = HSIC_HUB_RESET_GPIO;
+	}
+#endif
+	msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
+	msm8960_init_gpiomux();
+	msm8960_device_qup_spi_gsbi1.dev.platform_data =
+				&msm8960_qup_spi_gsbi1_pdata;
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+	msm8960_init_pmic();
+	msm8960_i2c_init();
+	msm8960_gfx_init();
+	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
+	msm_spm_l2_init(msm_spm_l2_data);
+	msm8960_init_buses();
+	platform_add_devices(msm_footswitch_devices,
+		msm_num_footswitch_devices);
+	if (machine_is_msm8960_liquid())
+		platform_device_register(&msm8960_device_ext_3p3v_vreg);
+	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	msm8960_pm8921_gpio_mpp_init();
+	platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
+	msm8960_init_hsic();
+	msm8960_init_cam();
+	msm8960_init_mmc();
+	acpuclk_init(&acpuclk_8960_soc_data);
+	if (machine_is_msm8960_liquid())
+		mxt_init_hw_liquid();
+	register_i2c_devices();
+	msm8960_init_fb();
+	slim_register_board_info(msm_slim_devices,
+		ARRAY_SIZE(msm_slim_devices));
+	msm8960_init_dsps();
+	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
+	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
+	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
+				msm_pm_data);
+	change_memory_power = &msm8960_change_memory_power;
+	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
+
+	if (PLATFORM_IS_CHARM25())
+		platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
+}
+
+MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
+	.map_io = msm8960_map_io,
+	.reserve = msm8960_reserve,
+	.init_irq = msm8960_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8960_sim_init,
+	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
+	.map_io = msm8960_map_io,
+	.reserve = msm8960_reserve,
+	.init_irq = msm8960_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8960_rumi3_init,
+	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8960_CDP, "QCT MSM8960 CDP")
+	.map_io = msm8960_map_io,
+	.reserve = msm8960_reserve,
+	.init_irq = msm8960_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8960_cdp_init,
+	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8960_MTP, "QCT MSM8960 MTP")
+	.map_io = msm8960_map_io,
+	.reserve = msm8960_reserve,
+	.init_irq = msm8960_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8960_cdp_init,
+	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8960_FLUID, "QCT MSM8960 FLUID")
+	.map_io = msm8960_map_io,
+	.reserve = msm8960_reserve,
+	.init_irq = msm8960_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8960_cdp_init,
+	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
+MACHINE_END
+
+MACHINE_START(MSM8960_LIQUID, "QCT MSM8960 LIQUID")
+	.map_io = msm8960_map_io,
+	.reserve = msm8960_reserve,
+	.init_irq = msm8960_init_irq,
+	.timer = &msm_timer,
+	.init_machine = msm8960_cdp_init,
+	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
new file mode 100644
index 0000000..56fa3ca
--- /dev/null
+++ b/arch/arm/mach-msm/board-8960.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2011, 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 __ARCH_ARM_MACH_MSM_BOARD_MSM8960_H
+#define __ARCH_ARM_MACH_MSM_BOARD_MSM8960_H
+
+#include <linux/regulator/gpio-regulator.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/i2c/sx150x.h>
+#include <mach/irqs.h>
+#include <mach/rpm-regulator.h>
+
+/* Macros assume PMIC GPIOs and MPPs start at 1 */
+#define PM8921_GPIO_BASE		NR_GPIO_IRQS
+#define PM8921_GPIO_PM_TO_SYS(pm_gpio)	(pm_gpio - 1 + PM8921_GPIO_BASE)
+#define PM8921_MPP_BASE			(PM8921_GPIO_BASE + PM8921_NR_GPIOS)
+#define PM8921_MPP_PM_TO_SYS(pm_gpio)	(pm_gpio - 1 + PM8921_MPP_BASE)
+#define PM8921_IRQ_BASE			(NR_MSM_IRQS + NR_GPIO_IRQS)
+
+extern struct pm8921_regulator_platform_data
+	msm_pm8921_regulator_pdata[] __devinitdata;
+
+extern int msm_pm8921_regulator_pdata_len __devinitdata;
+
+#define GPIO_VREG_ID_EXT_5V		0
+#define GPIO_VREG_ID_EXT_L2		1
+#define GPIO_VREG_ID_EXT_3P3V		2
+
+extern struct gpio_regulator_platform_data
+	msm_gpio_regulator_pdata[] __devinitdata;
+
+extern struct regulator_init_data msm_saw_regulator_pdata_s5;
+extern struct regulator_init_data msm_saw_regulator_pdata_s6;
+
+extern struct rpm_regulator_platform_data msm_rpm_regulator_pdata __devinitdata;
+
+#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
+enum {
+	GPIO_EXPANDER_IRQ_BASE = (PM8921_IRQ_BASE + PM8921_NR_IRQS),
+	GPIO_EXPANDER_GPIO_BASE = (PM8921_MPP_BASE + PM8921_NR_MPPS),
+	/* CAM Expander */
+	GPIO_CAM_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
+	GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
+	GPIO_CAM_GP_AFBUSY,
+	GPIO_CAM_GP_STROBE_CE,
+	GPIO_CAM_GP_CAM1MP_XCLR,
+	GPIO_CAM_GP_CAMIF_RESET_N,
+	GPIO_CAM_GP_XMT_FLASH_INT,
+	GPIO_CAM_GP_LED_EN1,
+	GPIO_CAM_GP_LED_EN2,
+
+};
+#endif
+
+enum {
+	SX150X_CAM,
+};
+
+#endif
+
+extern struct sx150x_platform_data msm8960_sx150x_data[];
+void msm8960_init_cam(void);
+void msm8960_init_fb(void);
+void msm8960_init_pmic(void);
+void msm8960_init_mmc(void);
+int msm8960_init_gpiomux(void);
+void msm8960_allocate_fb_region(void);
+void msm8960_pm8921_gpio_mpp_init(void);
+
+#define PLATFORM_IS_CHARM25() \
+	(machine_is_msm8960_cdp() && \
+		(socinfo_get_platform_subtype() == 1) \
+	)
+
+#define MSM_8960_GSBI4_QUP_I2C_BUS_ID 4
+#define MSM_8960_GSBI3_QUP_I2C_BUS_ID 3
+#define MSM_8960_GSBI10_QUP_I2C_BUS_ID 10
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 44b78d1..0a2e102 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -89,7 +89,7 @@
 
 static struct pm8xxx_pwrkey_platform_data pm8xxx_pwrkey_pdata = {
 	.pull_up		= 1,
-	.kpd_trigger_delay_us	= 970,
+	.kpd_trigger_delay_us	= 15625,
 	.wakeup			= 1,
 };
 
@@ -674,6 +674,14 @@
 	vbus_is_on = false;
 }
 
+static int shelby_phy_init_seq[] = {
+	0x44, 0x80,/* set VBUS valid threshold and
+			disconnect valid threshold */
+	0x38, 0x81, /* update DC voltage level */
+	0x14, 0x82,/* set preemphasis and rise/fall time */
+	0x13, 0x83,/* set source impedance adjustment */
+	-1};
+
 static struct msm_otg_platform_data msm_otg_pdata = {
 	.mode			= USB_OTG,
 	.otg_control	= OTG_PHY_CONTROL,
@@ -766,6 +774,7 @@
 	pm8018_platform_data.num_regulators = msm_pm8018_regulator_pdata_len;
 
 	msm_device_otg.dev.platform_data = &msm_otg_pdata;
+	msm_otg_pdata.phy_init_seq = shelby_phy_init_seq;
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 
 	acpuclk_init(&acpuclk_9615_soc_data);
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index a2ddeb4..13d63d3 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -83,6 +83,9 @@
 	CLK_DUMMY("usb_phy_clk", NULL, NULL, OFF),
 	CLK_DUMMY("usb_hs_clk", NULL, NULL, OFF),
 	CLK_DUMMY("usb_hs_pclk", NULL, NULL, OFF),
+	CLK_DUMMY("dfab_clk",	DFAB_CLK,	NULL, 0),
+	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK,	NULL, 0),
+	CLK_DUMMY("mem_clk",	NULL,	NULL, 0),
 };
 
 struct clock_init_data msm_dummy_clock_init_data __initdata = {
@@ -91,7 +94,7 @@
 };
 
 static struct of_dev_auxdata msm_copper_auxdata_lookup[] __initdata = {
-	OF_DEV_AUXDATA("qcom,msm-lsuart-v14", 0xF9684000, \
+	OF_DEV_AUXDATA("qcom,msm-lsuart-v14", 0xF991F000, \
 			"msm_serial_hsl.0", NULL),
 	{}
 };
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 1a085de..ebe884de 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -16,10 +16,48 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <asm/arch_timer.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/time.h>
 #include <mach/socinfo.h>
 #include <mach/board.h>
-#include "timer.h"
+
+static void __init msm_dt_timer_init(void)
+{
+	struct device_node *node;
+	struct resource res;
+	struct of_irq oirq;
+
+	node = of_find_compatible_node(NULL, NULL, "qcom,msm-qtimer");
+	if (!node) {
+		pr_err("no matching timer node found\n");
+		return;
+	}
+
+	if (of_irq_map_one(node, 0, &oirq)) {
+		pr_err("interrupt not specified in timer node\n");
+	} else {
+		res.start = res.end = oirq.specifier[0];
+		res.flags = IORESOURCE_IRQ;
+		arch_timer_register(&res, 1);
+	}
+	of_node_put(node);
+}
+
+static struct sys_timer msm_dt_timer = {
+	.init = msm_dt_timer_init
+};
+
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+	return 0;
+}
+
+int local_timer_ack(void)
+{
+	return 1;
+}
 
 static void __init msm_dt_init_irq(void)
 {
@@ -56,6 +94,6 @@
 	.map_io = msm_dt_map_io,
 	.init_irq = msm_dt_init_irq,
 	.init_machine = msm_dt_init,
-	.timer = &msm_timer,
+	.timer = &msm_dt_timer,
 	.dt_compat = msm_dt_match,
 MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7627-regulator.c b/arch/arm/mach-msm/board-msm7627-regulator.c
index 0b3baff..7437911 100644
--- a/arch/arm/mach-msm/board-msm7627-regulator.c
+++ b/arch/arm/mach-msm/board-msm7627-regulator.c
@@ -207,7 +207,7 @@
 	PCOM_VREG_LDO(ldo10,  7, NULL,  2600000,  2600000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo11, 21, NULL,  1800000,  1800000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo12, 11, NULL,  1800000,  1800000, 0, -1, 0, 0, 0, 0),
-	PCOM_VREG_LDO(ldo13, 15, NULL,  2850000,  2850000, 0, -1, 0, 0, 0, 0),
+	PCOM_VREG_LDO(ldo13, 15, NULL,  1800000,  2850000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo14, 24, NULL,  2700000,  2700000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo15, 23, NULL,  2600000,  2600000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo16, 22, NULL,  2850000,  3000000, 0, -1, 0, 0, 0, 0),
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 05b4896..5de5ea3 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1072,7 +1072,7 @@
 #define MSM_PMEM_MDP_SIZE       0x1900000
 #define MSM7x25A_MSM_PMEM_MDP_SIZE	0x1000000
 
-#define MSM_PMEM_ADSP_SIZE      0x2000000
+#define MSM_PMEM_ADSP_SIZE      0x1000000
 #define MSM7x25A_MSM_PMEM_ADSP_SIZE      0xB91000
 
 
@@ -3023,7 +3023,6 @@
 	gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
 				GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
 				GPIO_CFG_2MA), GPIO_CFG_DISABLE);
-	regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
 	regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
 	return 0;
 }
diff --git a/arch/arm/mach-msm/board-msm7x30-regulator.c b/arch/arm/mach-msm/board-msm7x30-regulator.c
index 5329bbe..edfcc6b 100644
--- a/arch/arm/mach-msm/board-msm7x30-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x30-regulator.c
@@ -289,7 +289,7 @@
 	PCOM_VREG_LDO(ldo10,  7, NULL,  2600000,  2600000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo11, 21, NULL,  2600000,  2600000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo12, 34, NULL,  1800000,  1800000, 0, -1, 0, 0, 0, 0),
-	PCOM_VREG_LDO(ldo13, 15, NULL,  2900000,  2900000, 0, -1, 0, 0, 0, 0),
+	PCOM_VREG_LDO(ldo13, 15, NULL,  2900000,  3050000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo14, 24, NULL,  2850000,  2850000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo15, 23, NULL,  3050000,  3100000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo16, 35, NULL,  2600000,  2600000, 0, -1, 0, 0, 0, 0),
@@ -298,7 +298,7 @@
 	PCOM_VREG_LDO(ldo19, 45, NULL,  2500000,  2500000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo20, 38, NULL,  1500000,  1800000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo21, 39, NULL,  1100000,  1100000, 0, -1, 0, 0, 0, 0),
-	PCOM_VREG_LDO(ldo22, 40, NULL,  1300000,  1300000, 0, -1, 0, 0, 0, 0),
+	PCOM_VREG_LDO(ldo22, 40, NULL,  1200000,  1300000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo23, 22, NULL,  1350000,  1350000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo24, 41, NULL,  1200000,  1200000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo25, 42, NULL,  1200000,  1200000, 0, -1, 0, 0, 0, 0),
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index d73f612..9ba92ed 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -4565,20 +4565,20 @@
 	{ .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
 	{ .supply = "smps2", .min_uV = 1300000, .max_uV = 1300000 },
 	{ .supply = "ldo24", .min_uV = 1200000, .max_uV = 1200000 },
-	{ .supply = "ldo13", .min_uV = 2900000, .max_uV = 2900000 },
+	{ .supply = "ldo13", .min_uV = 2900000, .max_uV = 3050000 },
 };
 
 static struct regulator_bulk_data regs_bt_bahama_v1[] = {
 	{ .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
 	{ .supply = "ldo7",  .min_uV = 1800000, .max_uV = 1800000 },
 	{ .supply = "smps2", .min_uV = 1300000, .max_uV = 1300000 },
-	{ .supply = "ldo13", .min_uV = 2900000, .max_uV = 2900000 },
+	{ .supply = "ldo13", .min_uV = 2900000, .max_uV = 3050000 },
 };
 
 static struct regulator_bulk_data regs_bt_bahama_v2[] = {
 	{ .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
 	{ .supply = "ldo7",  .min_uV = 1800000, .max_uV = 1800000 },
-	{ .supply = "ldo13", .min_uV = 2900000, .max_uV = 2900000 },
+	{ .supply = "ldo13", .min_uV = 2900000, .max_uV = 3050000 },
 };
 
 static struct regulator_bulk_data *regs_bt;
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
deleted file mode 100644
index 61423a6..0000000
--- a/arch/arm/mach-msm/board-msm8960.c
+++ /dev/null
@@ -1,5079 +0,0 @@
-/* Copyright (c) 2011, 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/platform_device.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/i2c.h>
-#include <linux/i2c/sx150x.h>
-#include <linux/i2c/isl9519.h>
-#include <linux/gpio.h>
-#include <linux/msm_ssbi.h>
-#include <linux/regulator/gpio-regulator.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
-#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spi/spi.h>
-#include <linux/slimbus/slimbus.h>
-#include <linux/bootmem.h>
-#include <linux/msm_kgsl.h>
-#ifdef CONFIG_ANDROID_PMEM
-#include <linux/android_pmem.h>
-#endif
-#include <linux/cyttsp.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_data/qcom_crypto_device.h>
-#include <linux/platform_data/qcom_wcnss_device.h>
-#include <linux/leds.h>
-#include <linux/leds-pm8xxx.h>
-#include <linux/i2c/atmel_mxt_ts.h>
-#include <linux/msm_tsens.h>
-#include <linux/ks8851.h>
-#include <linux/i2c/isa1200.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/setup.h>
-#include <asm/hardware/gic.h>
-#include <asm/mach/mmc.h>
-
-#include <mach/board.h>
-#include <mach/msm_iomap.h>
-#include <mach/msm_spi.h>
-#ifdef CONFIG_USB_MSM_OTG_72K
-#include <mach/msm_hsusb.h>
-#else
-#include <linux/usb/msm_hsusb.h>
-#endif
-#include <linux/usb/android.h>
-#include <mach/usbdiag.h>
-#include <mach/socinfo.h>
-#include <mach/rpm.h>
-#include <mach/gpio.h>
-#include <mach/gpiomux.h>
-#include <mach/msm_bus_board.h>
-#include <mach/msm_memtypes.h>
-#include <mach/dma.h>
-#include <mach/msm_dsps.h>
-#include <mach/msm_xo.h>
-#include <mach/restart.h>
-
-#ifdef CONFIG_WCD9310_CODEC
-#include <linux/slimbus/slimbus.h>
-#include <linux/mfd/wcd9310/core.h>
-#include <linux/mfd/wcd9310/pdata.h>
-#endif
-
-#include <linux/ion.h>
-#include <mach/ion.h>
-#include <mach/mdm2.h>
-
-#include "timer.h"
-#include "devices.h"
-#include "devices-msm8x60.h"
-#include "spm.h"
-#include "board-msm8960.h"
-#include "pm.h"
-#include "cpuidle.h"
-#include "rpm_resources.h"
-#include "mpm.h"
-#include "acpuclock.h"
-#include "rpm_log.h"
-#include "smd_private.h"
-#include "pm-boot.h"
-#include "msm_watchdog.h"
-
-#define PLATFORM_IS_CHARM25() \
-	(machine_is_msm8960_cdp() && \
-		(socinfo_get_platform_subtype() == 1) \
-	)
-
-static struct platform_device msm_fm_platform_init = {
-	.name = "iris_fm",
-	.id   = -1,
-};
-
-struct pm8xxx_gpio_init {
-	unsigned			gpio;
-	struct pm_gpio			config;
-};
-
-struct pm8xxx_mpp_init {
-	unsigned			mpp;
-	struct pm8xxx_mpp_config_data	config;
-};
-
-#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
-			_func, _inv, _disable) \
-{ \
-	.gpio	= PM8921_GPIO_PM_TO_SYS(_gpio), \
-	.config	= { \
-		.direction	= _dir, \
-		.output_buffer	= _buf, \
-		.output_value	= _val, \
-		.pull		= _pull, \
-		.vin_sel	= _vin, \
-		.out_strength	= _out_strength, \
-		.function	= _func, \
-		.inv_int_pol	= _inv, \
-		.disable_pin	= _disable, \
-	} \
-}
-
-#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
-{ \
-	.mpp	= PM8921_MPP_PM_TO_SYS(_mpp), \
-	.config	= { \
-		.type		= PM8XXX_MPP_TYPE_##_type, \
-		.level		= _level, \
-		.control	= PM8XXX_MPP_##_control, \
-	} \
-}
-
-#define PM8XXX_GPIO_DISABLE(_gpio) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
-			 0, 0, 0, 1)
-
-#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
-			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
-			PM_GPIO_STRENGTH_HIGH, \
-			PM_GPIO_FUNC_NORMAL, 0, 0)
-
-#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
-			_pull, PM_GPIO_VIN_S4, \
-			PM_GPIO_STRENGTH_NO, \
-			PM_GPIO_FUNC_NORMAL, 0, 0)
-
-#define PM8XXX_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
-			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
-			PM_GPIO_STRENGTH_HIGH, \
-			_func, 0, 0)
-
-#define PM8XXX_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
-	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
-			PM_GPIO_PULL_NO, _vin, \
-			PM_GPIO_STRENGTH_HIGH, \
-			PM_GPIO_FUNC_NORMAL, 0, 0)
-
-/* Initial PM8921 GPIO configurations */
-static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
-	PM8XXX_GPIO_DISABLE(6),				 /* Disable unused */
-	PM8XXX_GPIO_DISABLE(7),				 /* Disable NFC */
-	PM8XXX_GPIO_INPUT(16,	    PM_GPIO_PULL_UP_30), /* SD_CARD_WP */
-    /* External regulator shared by display and touchscreen on LiQUID */
-	PM8XXX_GPIO_OUTPUT(17,	    0),			 /* DISP 3.3 V Boost */
-	PM8XXX_GPIO_OUTPUT_VIN(21, 1, PM_GPIO_VIN_VPH),	 /* Backlight Enable */
-	PM8XXX_GPIO_DISABLE(22),			 /* Disable NFC */
-	PM8XXX_GPIO_OUTPUT_FUNC(24, 0, PM_GPIO_FUNC_2),	 /* Bl: Off, PWM mode */
-	PM8XXX_GPIO_INPUT(26,	    PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
-	PM8XXX_GPIO_OUTPUT(43,	    PM_GPIO_PULL_UP_30), /* DISP_RESET_N */
-	PM8XXX_GPIO_OUTPUT(42, 0),                      /* USB 5V reg enable */
-};
-
-/* Initial PM8921 MPP configurations */
-static struct pm8xxx_mpp_init pm8921_mpps[] __initdata = {
-	/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
-	PM8XXX_MPP_INIT(7, D_INPUT, PM8921_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
-	PM8XXX_MPP_INIT(PM8XXX_AMUX_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
-								DOUT_CTRL_LOW),
-};
-
-static void __init pm8921_gpio_mpp_init(void)
-{
-	int i, rc;
-
-	for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
-		rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
-					&pm8921_gpios[i].config);
-		if (rc) {
-			pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
-			break;
-		}
-	}
-
-	for (i = 0; i < ARRAY_SIZE(pm8921_mpps); i++) {
-		rc = pm8xxx_mpp_config(pm8921_mpps[i].mpp,
-					&pm8921_mpps[i].config);
-		if (rc) {
-			pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
-			break;
-		}
-	}
-}
-
-#define KS8851_RST_GPIO		89
-#define KS8851_IRQ_GPIO		90
-
-#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
-enum {
-	GPIO_EXPANDER_IRQ_BASE = (PM8921_IRQ_BASE + PM8921_NR_IRQS),
-	GPIO_EXPANDER_GPIO_BASE = (PM8921_MPP_BASE + PM8921_NR_MPPS),
-	/* CAM Expander */
-	GPIO_CAM_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
-	GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
-	GPIO_CAM_GP_AFBUSY,
-	GPIO_CAM_GP_STROBE_CE,
-	GPIO_CAM_GP_CAM1MP_XCLR,
-	GPIO_CAM_GP_CAMIF_RESET_N,
-	GPIO_CAM_GP_XMT_FLASH_INT,
-	GPIO_CAM_GP_LED_EN1,
-	GPIO_CAM_GP_LED_EN2,
-
-};
-#endif
-
-/* The SPI configurations apply to GSBI 1*/
-static struct gpiomux_setting spi_active = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_12MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting spi_suspended_config = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting spi_active_config2 = {
-	.func = GPIOMUX_FUNC_2,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting spi_suspended_config2 = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting gsbi3_suspended_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_KEEPER,
-};
-
-static struct gpiomux_setting gsbi3_active_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi5 = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi10 = {
-	.func = GPIOMUX_FUNC_2,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting gsbi12 = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting cdc_mclk = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting audio_auxpcm[] = {
-	/* Suspended state */
-	{
-		.func = GPIOMUX_FUNC_GPIO,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_NONE,
-	},
-	/* Active state */
-	{
-		.func = GPIOMUX_FUNC_1,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_NONE,
-	},
-};
-
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
-static struct gpiomux_setting gpio_eth_config = {
-	.pull = GPIOMUX_PULL_NONE,
-	.drv = GPIOMUX_DRV_8MA,
-	.func = GPIOMUX_FUNC_GPIO,
-};
-#endif
-
-static struct gpiomux_setting slimbus = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_KEEPER,
-};
-
-struct msm_gpiomux_config msm8960_gpiomux_configs[NR_GPIO_IRQS] = {
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
-	{
-		.gpio = KS8851_IRQ_GPIO,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
-		}
-	},
-	{
-		.gpio = KS8851_RST_GPIO,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
-		}
-	},
-#endif
-};
-
-static struct msm_gpiomux_config msm8960_gsbi_configs[] __initdata = {
-	{
-		.gpio      = 6,		/* GSBI1 QUP SPI_DATA_MOSI */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
-			[GPIOMUX_ACTIVE] = &spi_active,
-		},
-	},
-	{
-		.gpio      = 7,		/* GSBI1 QUP SPI_DATA_MISO */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
-			[GPIOMUX_ACTIVE] = &spi_active,
-		},
-	},
-	{
-		.gpio      = 8,		/* GSBI1 QUP SPI_CS_N */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
-			[GPIOMUX_ACTIVE] = &spi_active,
-		},
-	},
-	{
-		.gpio      = 9,		/* GSBI1 QUP SPI_CLK */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &spi_suspended_config,
-			[GPIOMUX_ACTIVE] = &spi_active,
-		},
-	},
-	{
-		.gpio      = 14,		/* GSBI1 SPI_CS_1 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &spi_suspended_config2,
-			[GPIOMUX_ACTIVE] = &spi_active_config2,
-		},
-	},
-	{
-		.gpio      = 16,	/* GSBI3 I2C QUP SDA */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
-			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
-		},
-	},
-	{
-		.gpio      = 17,	/* GSBI3 I2C QUP SCL */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
-			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
-		},
-	},
-	{
-		.gpio      = 22,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
-		.gpio      = 23,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
-		.gpio      = 24,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
-		.gpio      = 25,	/* GSBI5 UART2 */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi5,
-		},
-	},
-	{
-		.gpio      = 44,	/* GSBI12 I2C QUP SDA */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi12,
-		},
-	},
-	{
-		.gpio      = 45,	/* GSBI12 I2C QUP SCL */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi12,
-		},
-	},
-	{
-		.gpio      = 73,	/* GSBI10 I2C QUP SDA */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi10,
-		},
-	},
-	{
-		.gpio      = 74,	/* GSBI10 I2C QUP SCL */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gsbi10,
-		},
-	},
-};
-
-static struct msm_gpiomux_config msm8960_slimbus_config[] __initdata = {
-	{
-		.gpio	= 60,		/* slimbus data */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &slimbus,
-		},
-	},
-	{
-		.gpio	= 61,		/* slimbus clk */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &slimbus,
-		},
-	},
-};
-
-static struct msm_gpiomux_config msm8960_audio_codec_configs[] __initdata = {
-	{
-		.gpio = 59,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &cdc_mclk,
-		},
-	},
-};
-
-static struct msm_gpiomux_config msm8960_audio_auxpcm_configs[] __initdata = {
-	{
-		.gpio = 63,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-	{
-		.gpio = 64,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-	{
-		.gpio = 65,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-	{
-		.gpio = 66,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-};
-
-static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv  = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting wcnss_5wire_active_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv  = GPIOMUX_DRV_6MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config wcnss_5wire_interface[] = {
-	{
-		.gpio = 84,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
-			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
-		},
-	},
-	{
-		.gpio = 85,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
-			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
-		},
-	},
-	{
-		.gpio = 86,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
-			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
-		},
-	},
-	{
-		.gpio = 87,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
-			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
-		},
-	},
-	{
-		.gpio = 88,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
-			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
-		},
-	},
-};
-static struct gpiomux_setting cam_settings[] = {
-	{
-		.func = GPIOMUX_FUNC_GPIO, /*suspend*/
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_DOWN,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_1, /*active 1*/
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_NONE,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_GPIO, /*active 2*/
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_NONE,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_1, /*active 3*/
-		.drv = GPIOMUX_DRV_8MA,
-		.pull = GPIOMUX_PULL_NONE,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_5, /*active 4*/
-		.drv = GPIOMUX_DRV_8MA,
-		.pull = GPIOMUX_PULL_UP,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_6, /*active 5*/
-		.drv = GPIOMUX_DRV_8MA,
-		.pull = GPIOMUX_PULL_UP,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_2, /*active 6*/
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_UP,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_3, /*active 7*/
-		.drv = GPIOMUX_DRV_8MA,
-		.pull = GPIOMUX_PULL_UP,
-	},
-
-	{
-		.func = GPIOMUX_FUNC_GPIO, /*i2c suspend*/
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_KEEPER,
-	},
-
-};
-
-static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
-	{
-		.gpio = 2,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[2],
-			[GPIOMUX_SUSPENDED] = &cam_settings[0],
-		},
-	},
-	{
-		.gpio = 3,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[1],
-			[GPIOMUX_SUSPENDED] = &cam_settings[0],
-		},
-	},
-	{
-		.gpio = 4,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[1],
-			[GPIOMUX_SUSPENDED] = &cam_settings[0],
-		},
-	},
-	{
-		.gpio = 5,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[1],
-			[GPIOMUX_SUSPENDED] = &cam_settings[0],
-		},
-	},
-	{
-		.gpio = 76,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[2],
-			[GPIOMUX_SUSPENDED] = &cam_settings[0],
-		},
-	},
-	{
-		.gpio = 107,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[2],
-			[GPIOMUX_SUSPENDED] = &cam_settings[0],
-		},
-	},
-};
-
-static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
-	{
-		.gpio = 18,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[3],
-			[GPIOMUX_SUSPENDED] = &cam_settings[8],
-		},
-	},
-	{
-		.gpio = 19,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[3],
-			[GPIOMUX_SUSPENDED] = &cam_settings[8],
-		},
-	},
-	{
-		.gpio = 20,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[3],
-			[GPIOMUX_SUSPENDED] = &cam_settings[8],
-		},
-	},
-	{
-		.gpio = 21,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cam_settings[3],
-			[GPIOMUX_SUSPENDED] = &cam_settings[8],
-		},
-	},
-};
-
-static struct gpiomux_setting cyts_resout_sus_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_6MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_resout_act_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_6MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_sleep_sus_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_6MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting cyts_sleep_act_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_6MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting cyts_int_act_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting cyts_int_sus_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_cyts_configs[] __initdata = {
-	{	/* TS INTERRUPT */
-		.gpio = 11,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cyts_int_act_cfg,
-			[GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
-		},
-	},
-	{	/* TS SLEEP */
-		.gpio = 50,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cyts_sleep_act_cfg,
-			[GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
-		},
-	},
-	{	/* TS RESOUT */
-		.gpio = 52,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &cyts_resout_act_cfg,
-			[GPIOMUX_SUSPENDED] = &cyts_resout_sus_cfg,
-		},
-	},
-};
-
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-static struct gpiomux_setting hsic_act_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_12MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting hsic_sus_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-	.dir = GPIOMUX_OUT_LOW,
-};
-
-static struct gpiomux_setting hsic_hub_act_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct msm_gpiomux_config msm8960_hsic_configs[] = {
-	{
-		.gpio = 150,               /*HSIC_STROBE */
-		.settings = {
-			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
-			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
-		},
-	},
-	{
-		.gpio = 151,               /* HSIC_DATA */
-		.settings = {
-			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
-			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
-		},
-	},
-	{
-		.gpio = 91,               /* HSIC_HUB_RESET */
-		.settings = {
-			[GPIOMUX_ACTIVE] = &hsic_hub_act_cfg,
-			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
-		},
-	},
-};
-#endif
-
-#define HAP_SHIFT_LVL_OE_GPIO	47
-
-static struct gpiomux_setting hap_lvl_shft_suspended_config = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting hap_lvl_shft_active_config = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
-static struct msm_gpiomux_config hap_lvl_shft_config[] __initdata = {
-	{
-		.gpio = HAP_SHIFT_LVL_OE_GPIO,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &hap_lvl_shft_suspended_config,
-			[GPIOMUX_ACTIVE] = &hap_lvl_shft_active_config,
-		},
-	},
-};
-
-#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
-enum {
-	SX150X_CAM,
-};
-
-static struct sx150x_platform_data sx150x_data[] = {
-	[SX150X_CAM] = {
-		.gpio_base         = GPIO_CAM_EXPANDER_BASE,
-		.oscio_is_gpo      = false,
-		.io_pullup_ena     = 0x0,
-		.io_pulldn_ena     = 0xc0,
-		.io_open_drain_ena = 0x0,
-		.irq_summary       = -1,
-	},
-};
-
-#endif
-
-#ifdef CONFIG_I2C
-
-#define MSM_8960_GSBI4_QUP_I2C_BUS_ID 4
-#define MSM_8960_GSBI3_QUP_I2C_BUS_ID 3
-#define MSM_8960_GSBI10_QUP_I2C_BUS_ID 10
-
-#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
-
-static struct i2c_board_info cam_expander_i2c_info[] = {
-	{
-		I2C_BOARD_INFO("sx1508q", 0x22),
-		.platform_data = &sx150x_data[SX150X_CAM]
-	},
-};
-
-static struct msm_cam_expander_info cam_expander_info[] = {
-	{
-		cam_expander_i2c_info,
-		MSM_8960_GSBI4_QUP_I2C_BUS_ID,
-	},
-};
-#endif
-#endif
-
-#define MSM_PMEM_ADSP_SIZE         0x3800000
-#define MSM_PMEM_AUDIO_SIZE        0x28B000
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
-#else
-#define MSM_PMEM_SIZE 0x1C00000 /* 28 Mbytes */
-#endif
-
-
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-#define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
-#define MSM_ION_EBI_SIZE	(MSM_PMEM_SIZE + 0x600000)
-#define MSM_ION_ADSP_SIZE	MSM_PMEM_ADSP_SIZE
-#define MSM_ION_HEAP_NUM	4
-#else
-#define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
-#define MSM_ION_HEAP_NUM	2
-#endif
-
-#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
-static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
-static int __init pmem_kernel_ebi1_size_setup(char *p)
-{
-	pmem_kernel_ebi1_size = memparse(p, NULL);
-	return 0;
-}
-early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
-#endif
-
-#ifdef CONFIG_ANDROID_PMEM
-static unsigned pmem_size = MSM_PMEM_SIZE;
-static int __init pmem_size_setup(char *p)
-{
-	pmem_size = memparse(p, NULL);
-	return 0;
-}
-early_param("pmem_size", pmem_size_setup);
-
-static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
-
-static int __init pmem_adsp_size_setup(char *p)
-{
-	pmem_adsp_size = memparse(p, NULL);
-	return 0;
-}
-early_param("pmem_adsp_size", pmem_adsp_size_setup);
-
-static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE;
-
-static int __init pmem_audio_size_setup(char *p)
-{
-	pmem_audio_size = memparse(p, NULL);
-	return 0;
-}
-early_param("pmem_audio_size", pmem_audio_size_setup);
-#endif
-
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-static struct android_pmem_platform_data android_pmem_pdata = {
-	.name = "pmem",
-	.allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
-	.cached = 1,
-	.memory_type = MEMTYPE_EBI1,
-};
-
-static struct platform_device android_pmem_device = {
-	.name = "android_pmem",
-	.id = 0,
-	.dev = {.platform_data = &android_pmem_pdata},
-};
-
-static struct android_pmem_platform_data android_pmem_adsp_pdata = {
-	.name = "pmem_adsp",
-	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
-	.cached = 0,
-	.memory_type = MEMTYPE_EBI1,
-};
-static struct platform_device android_pmem_adsp_device = {
-	.name = "android_pmem",
-	.id = 2,
-	.dev = { .platform_data = &android_pmem_adsp_pdata },
-};
-#endif
-
-static struct android_pmem_platform_data android_pmem_audio_pdata = {
-	.name = "pmem_audio",
-	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
-	.cached = 0,
-	.memory_type = MEMTYPE_EBI1,
-};
-
-static struct platform_device android_pmem_audio_device = {
-	.name = "android_pmem",
-	.id = 4,
-	.dev = { .platform_data = &android_pmem_audio_pdata },
-};
-#endif
-
-#define DSP_RAM_BASE_8960 0x8da00000
-#define DSP_RAM_SIZE_8960 0x1800000
-static int dspcrashd_pdata_8960 = 0xDEADDEAD;
-
-static struct resource resources_dspcrashd_8960[] = {
-	{
-		.name   = "msm_dspcrashd",
-		.start  = DSP_RAM_BASE_8960,
-		.end    = DSP_RAM_BASE_8960 + DSP_RAM_SIZE_8960,
-		.flags  = IORESOURCE_DMA,
-	},
-};
-
-struct platform_device msm_device_dspcrashd_8960 = {
-	.name           = "msm_dspcrashd",
-	.num_resources  = ARRAY_SIZE(resources_dspcrashd_8960),
-	.resource       = resources_dspcrashd_8960,
-	.dev = { .platform_data = &dspcrashd_pdata_8960 },
-};
-
-static struct memtype_reserve msm8960_reserve_table[] __initdata = {
-	[MEMTYPE_SMI] = {
-	},
-	[MEMTYPE_EBI0] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-	[MEMTYPE_EBI1] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-};
-
-static void __init size_pmem_devices(void)
-{
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	android_pmem_adsp_pdata.size = pmem_adsp_size;
-	android_pmem_pdata.size = pmem_size;
-#endif
-	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
-#endif
-}
-
-static void __init reserve_memory_for(struct android_pmem_platform_data *p)
-{
-	msm8960_reserve_table[p->memory_type].size += p->size;
-}
-
-static void __init reserve_pmem_memory(void)
-{
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	reserve_memory_for(&android_pmem_adsp_pdata);
-	reserve_memory_for(&android_pmem_pdata);
-#endif
-	reserve_memory_for(&android_pmem_audio_pdata);
-	msm8960_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
-#endif
-}
-
-static int msm8960_paddr_to_memtype(unsigned int paddr)
-{
-	return MEMTYPE_EBI1;
-}
-
-#ifdef CONFIG_ION_MSM
-struct ion_platform_data ion_pdata = {
-	.nr = MSM_ION_HEAP_NUM,
-	.heaps = {
-		{
-			.id	= ION_HEAP_SYSTEM_ID,
-			.type	= ION_HEAP_TYPE_SYSTEM,
-			.name	= ION_KMALLOC_HEAP_NAME,
-		},
-		{
-			.id	= ION_HEAP_SYSTEM_CONTIG_ID,
-			.type	= ION_HEAP_TYPE_SYSTEM_CONTIG,
-			.name	= ION_VMALLOC_HEAP_NAME,
-		},
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		{
-			.id	= ION_HEAP_EBI_ID,
-			.type	= ION_HEAP_TYPE_CARVEOUT,
-			.name	= ION_EBI1_HEAP_NAME,
-			.size	= MSM_ION_EBI_SIZE,
-			.memory_type = ION_EBI_TYPE,
-		},
-		{
-			.id	= ION_HEAP_ADSP_ID,
-			.type	= ION_HEAP_TYPE_CARVEOUT,
-			.name	= ION_ADSP_HEAP_NAME,
-			.size	= MSM_ION_ADSP_SIZE,
-			.memory_type = ION_EBI_TYPE,
-		},
-#endif
-	}
-};
-
-struct platform_device ion_dev = {
-	.name = "ion-msm",
-	.id = 1,
-	.dev = { .platform_data = &ion_pdata },
-};
-#endif
-
-static void reserve_ion_memory(void)
-{
-#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
-	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_EBI_SIZE;
-	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_ADSP_SIZE;
-#endif
-}
-static void __init msm8960_calculate_reserve_sizes(void)
-{
-	size_pmem_devices();
-	reserve_pmem_memory();
-	reserve_ion_memory();
-}
-
-static struct reserve_info msm8960_reserve_info __initdata = {
-	.memtype_reserve_table = msm8960_reserve_table,
-	.calculate_reserve_sizes = msm8960_calculate_reserve_sizes,
-	.paddr_to_memtype = msm8960_paddr_to_memtype,
-};
-
-static int msm8960_memory_bank_size(void)
-{
-	return 1<<29;
-}
-
-static void __init locate_unstable_memory(void)
-{
-	struct membank *mb = &meminfo.bank[meminfo.nr_banks - 1];
-	unsigned long bank_size;
-	unsigned long low, high;
-
-	bank_size = msm8960_memory_bank_size();
-	low = meminfo.bank[0].start;
-	high = mb->start + mb->size;
-
-	/* Check if 32 bit overflow occured */
-	if (high < mb->start)
-		high = ~0UL;
-
-	low &= ~(bank_size - 1);
-
-	if (high - low <= bank_size)
-		return;
-	msm8960_reserve_info.low_unstable_address = low + bank_size;
-	/* To avoid overflow of u32 compute max_unstable_size
-	 * by first subtracting low from mb->start)
-	 * */
-	msm8960_reserve_info.max_unstable_size = (mb->start - low) +
-						mb->size - bank_size;
-
-	msm8960_reserve_info.bank_size = bank_size;
-	pr_info("low unstable address %lx max size %lx bank size %lx\n",
-		msm8960_reserve_info.low_unstable_address,
-		msm8960_reserve_info.max_unstable_size,
-		msm8960_reserve_info.bank_size);
-}
-
-static void __init place_movable_zone(void)
-{
-	movable_reserved_start = msm8960_reserve_info.low_unstable_address;
-	movable_reserved_size = msm8960_reserve_info.max_unstable_size;
-	pr_info("movable zone start %lx size %lx\n",
-		movable_reserved_start, movable_reserved_size);
-}
-
-static void __init msm8960_early_memory(void)
-{
-	reserve_info = &msm8960_reserve_info;
-	locate_unstable_memory();
-	place_movable_zone();
-}
-
-static void __init msm8960_reserve(void)
-{
-	msm_reserve();
-}
-
-static int msm8960_change_memory_power(u64 start, u64 size,
-	int change_type)
-{
-	return soc_change_memory_power(start, size, change_type);
-}
-
-#ifdef CONFIG_MSM_CAMERA
-
-static uint16_t msm_cam_gpio_2d_tbl[] = {
-	5, /*CAMIF_MCLK*/
-	20, /*CAMIF_I2C_DATA*/
-	21, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
-	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
-	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
-	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
-	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
-#define VFE_CAMIF_TIMER1_GPIO 2
-#define VFE_CAMIF_TIMER2_GPIO 3
-#define VFE_CAMIF_TIMER3_GPIO_INT 4
-struct msm_camera_sensor_strobe_flash_data strobe_flash_xenon = {
-	.flash_trigger = VFE_CAMIF_TIMER2_GPIO,
-	.flash_charge = VFE_CAMIF_TIMER1_GPIO,
-	.flash_charge_done = VFE_CAMIF_TIMER3_GPIO_INT,
-	.flash_recharge_duration = 50000,
-	.irq = MSM_GPIO_TO_INT(VFE_CAMIF_TIMER3_GPIO_INT),
-};
-
-#ifdef CONFIG_MSM_CAMERA_FLASH
-static struct msm_camera_sensor_flash_src msm_flash_src = {
-	.flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
-	._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
-	._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
-#if defined(CONFIG_I2C) && (defined(CONFIG_GPIO_SX150X) || \
-			defined(CONFIG_GPIO_SX150X_MODULE))
-	._fsrc.ext_driver_src.expander_info = cam_expander_info,
-#endif
-};
-#endif
-
-static struct msm_bus_vectors cam_init_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-	{
-		.src = MSM_BUS_MASTER_VPE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-	{
-		.src = MSM_BUS_MASTER_JPEG_ENC,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-};
-
-static struct msm_bus_vectors cam_preview_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 27648000,
-		.ib  = 110592000,
-	},
-	{
-		.src = MSM_BUS_MASTER_VPE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-	{
-		.src = MSM_BUS_MASTER_JPEG_ENC,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-};
-
-static struct msm_bus_vectors cam_video_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 140451840,
-		.ib  = 561807360,
-	},
-	{
-		.src = MSM_BUS_MASTER_VPE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 206807040,
-		.ib  = 488816640,
-	},
-	{
-		.src = MSM_BUS_MASTER_JPEG_ENC,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-};
-
-static struct msm_bus_vectors cam_snapshot_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 274423680,
-		.ib  = 1097694720,
-	},
-	{
-		.src = MSM_BUS_MASTER_VPE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-	{
-		.src = MSM_BUS_MASTER_JPEG_ENC,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 540000000,
-		.ib  = 1350000000,
-	},
-};
-
-static struct msm_bus_vectors cam_zsl_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_VFE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 302071680,
-		.ib  = 1208286720,
-	},
-	{
-		.src = MSM_BUS_MASTER_VPE,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 0,
-		.ib  = 0,
-	},
-	{
-		.src = MSM_BUS_MASTER_JPEG_ENC,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = 540000000,
-		.ib  = 1350000000,
-	},
-};
-
-static struct msm_bus_paths cam_bus_client_config[] = {
-	{
-		ARRAY_SIZE(cam_init_vectors),
-		cam_init_vectors,
-	},
-	{
-		ARRAY_SIZE(cam_preview_vectors),
-		cam_preview_vectors,
-	},
-	{
-		ARRAY_SIZE(cam_video_vectors),
-		cam_video_vectors,
-	},
-	{
-		ARRAY_SIZE(cam_snapshot_vectors),
-		cam_snapshot_vectors,
-	},
-	{
-		ARRAY_SIZE(cam_zsl_vectors),
-		cam_zsl_vectors,
-	},
-};
-
-static struct msm_bus_scale_pdata cam_bus_client_pdata = {
-		cam_bus_client_config,
-		ARRAY_SIZE(cam_bus_client_config),
-		.name = "msm_camera",
-};
-
-struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
-	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
-		.csid_core = 0,
-		.cam_bus_scale_table = &cam_bus_client_pdata,
-	},
-	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
-		.csid_core = 1,
-		.cam_bus_scale_table = &cam_bus_client_pdata,
-	},
-};
-
-#ifdef CONFIG_IMX074_ACT
-static struct i2c_board_info imx074_actuator_i2c_info = {
-	I2C_BOARD_INFO("imx074_act", 0x11),
-};
-
-static struct msm_actuator_info imx074_actuator_info = {
-	.board_info     = &imx074_actuator_i2c_info,
-	.bus_id         = MSM_8960_GSBI4_QUP_I2C_BUS_ID,
-	.vcm_pwd        = 0,
-	.vcm_enable     = 1,
-};
-#endif
-
-#ifdef CONFIG_IMX074
-static struct msm_camera_sensor_flash_data flash_imx074 = {
-	.flash_type	= MSM_CAMERA_FLASH_LED,
-#ifdef CONFIG_MSM_CAMERA_FLASH
-	.flash_src	= &msm_flash_src
-#endif
-};
-
-static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
-	.mount_angle	= 90,
-	.sensor_reset	= 107,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
-};
-
-static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
-	.sensor_name	= "imx074",
-	.pdata	= &msm_camera_csi_device_data[0],
-	.flash_data	= &flash_imx074,
-	.strobe_flash_data = &strobe_flash_xenon,
-	.sensor_platform_info = &sensor_board_info_imx074,
-	.gpio_conf = &gpio_conf,
-	.csi_if	= 1,
-	.camera_type = BACK_CAMERA_2D,
-#ifdef CONFIG_IMX074_ACT
-	.actuator_info = &imx074_actuator_info
-#endif
-};
-
-struct platform_device msm8960_camera_sensor_imx074 = {
-	.name	= "msm_camera_imx074",
-	.dev	= {
-		.platform_data = &msm_camera_sensor_imx074_data,
-	},
-};
-#endif
-#ifdef CONFIG_OV2720
-static struct msm_camera_sensor_flash_data flash_ov2720 = {
-	.flash_type	= MSM_CAMERA_FLASH_NONE,
-};
-
-static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
-	.mount_angle	= 0,
-	.sensor_reset	= 76,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
-};
-
-static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
-	.sensor_name	= "ov2720",
-	.pdata	= &msm_camera_csi_device_data[1],
-	.flash_data	= &flash_ov2720,
-	.sensor_platform_info = &sensor_board_info_ov2720,
-	.gpio_conf = &gpio_conf,
-	.csi_if	= 1,
-	.camera_type = FRONT_CAMERA_2D,
-};
-
-struct platform_device msm8960_camera_sensor_ov2720 = {
-	.name	= "msm_camera_ov2720",
-	.dev	= {
-		.platform_data = &msm_camera_sensor_ov2720_data,
-	},
-};
-#endif
-
-static struct msm8960_privacy_light_cfg privacy_light_info = {
-	.mpp = PM8921_MPP_PM_TO_SYS(12),
-};
-
-static void __init msm8960_init_cam(void)
-{
-	int i;
-	struct platform_device *cam_dev[] = {
-		&msm8960_camera_sensor_imx074,
-		&msm8960_camera_sensor_ov2720,
-	};
-
-	if (machine_is_msm8960_liquid()) {
-		struct msm_camera_sensor_info *s_info;
-		s_info = msm8960_camera_sensor_imx074.dev.platform_data;
-		s_info->sensor_platform_info->mount_angle = 180;
-		s_info = msm8960_camera_sensor_ov2720.dev.platform_data;
-		s_info->sensor_platform_info->privacy_light = 1;
-		s_info->sensor_platform_info->privacy_light_info =
-			&privacy_light_info;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(cam_dev); i++) {
-		struct msm_camera_sensor_info *s_info;
-		s_info = cam_dev[i]->dev.platform_data;
-		msm_get_cam_resources(s_info);
-		platform_device_register(cam_dev[i]);
-	}
-
-	platform_device_register(&msm8960_device_csiphy0);
-	platform_device_register(&msm8960_device_csiphy1);
-	platform_device_register(&msm8960_device_csid0);
-	platform_device_register(&msm8960_device_csid1);
-	platform_device_register(&msm8960_device_ispif);
-	platform_device_register(&msm8960_device_vfe);
-	platform_device_register(&msm8960_device_vpe);
-}
-#endif
-
-#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 3) /* 4 bpp x 3 pages */
-#else
-#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 2) /* 4 bpp x 2 pages */
-#endif
-
-
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-#define MSM_FB_EXT_BUF_SIZE	(1920 * 1088 * 2 * 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 */
-#else
-#define MSM_FB_EXT_BUF_SIZE	0
-#endif
-
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
-/* width x height x 3 bpp x 2 frame buffer */
-#define MSM_FB_WRITEBACK_SIZE (1376 * 768 * 3 * 2)
-#define MSM_FB_WRITEBACK_OFFSET  \
-		(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE)
-#else
-#define MSM_FB_WRITEBACK_SIZE   0
-#define MSM_FB_WRITEBACK_OFFSET 0
-#endif
-
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-/* 4 bpp x 2 page HDMI case */
-#define MSM_FB_SIZE roundup((1920 * 1088 * 4 * 2), 4096)
-#else
-/* Note: must be multiple of 4096 */
-#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + MSM_FB_EXT_BUF_SIZE + \
-				MSM_FB_WRITEBACK_SIZE, 4096)
-#endif
-
-static int writeback_offset(void)
-{
-	return MSM_FB_WRITEBACK_OFFSET;
-}
-
-
-#define MDP_VSYNC_GPIO 0
-
-#define PANEL_NAME_MAX_LEN	30
-#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME	"mipi_cmd_novatek_qhd"
-#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME	"mipi_video_novatek_qhd"
-#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME	"mipi_video_toshiba_wsvga"
-#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME	"mipi_video_chimei_wxga"
-#define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME	"mipi_video_simulator_vga"
-#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME	"mipi_cmd_renesas_fwvga"
-#define HDMI_PANEL_NAME	"hdmi_msm"
-#define TVOUT_PANEL_NAME	"tvout_msm"
-
-static struct resource msm_fb_resources[] = {
-	{
-		.flags = IORESOURCE_DMA,
-	}
-};
-
-static int msm_fb_detect_panel(const char *name)
-{
-	if (machine_is_msm8960_liquid()) {
-		if (!strncmp(name, MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
-				strnlen(MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME,
-					PANEL_NAME_MAX_LEN)))
-			return 0;
-	} else {
-		if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
-				strnlen(MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME,
-					PANEL_NAME_MAX_LEN)))
-			return 0;
-
-#ifndef CONFIG_FB_MSM_MIPI_PANEL_DETECT
-		if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
-				strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
-					PANEL_NAME_MAX_LEN)))
-			return 0;
-
-		if (!strncmp(name, MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
-				strnlen(MIPI_CMD_NOVATEK_QHD_PANEL_NAME,
-					PANEL_NAME_MAX_LEN)))
-			return 0;
-
-		if (!strncmp(name, MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
-				strnlen(MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME,
-					PANEL_NAME_MAX_LEN)))
-			return 0;
-
-		if (!strncmp(name, MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
-				strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
-					PANEL_NAME_MAX_LEN)))
-			return 0;
-#endif
-	}
-
-	if (!strncmp(name, HDMI_PANEL_NAME,
-			strnlen(HDMI_PANEL_NAME,
-				PANEL_NAME_MAX_LEN)))
-		return 0;
-
-	if (!strncmp(name, TVOUT_PANEL_NAME,
-			strnlen(TVOUT_PANEL_NAME,
-				PANEL_NAME_MAX_LEN)))
-		return 0;
-
-	pr_warning("%s: not supported '%s'", __func__, name);
-	return -ENODEV;
-}
-
-static struct msm_fb_platform_data msm_fb_pdata = {
-	.detect_client = msm_fb_detect_panel,
-};
-
-static struct platform_device msm_fb_device = {
-	.name   = "msm_fb",
-	.id     = 0,
-	.num_resources     = ARRAY_SIZE(msm_fb_resources),
-	.resource          = msm_fb_resources,
-	.dev.platform_data = &msm_fb_pdata,
-};
-
-static bool dsi_power_on;
-
-/**
- * LiQUID panel on/off
- *
- * @param on
- *
- * @return int
- */
-static int mipi_dsi_liquid_panel_power(int on)
-{
-	static struct regulator *reg_l2, *reg_ext_3p3v;
-	static int gpio21, gpio24, gpio43;
-	int rc;
-
-	pr_info("%s: on=%d\n", __func__, on);
-
-	gpio21 = PM8921_GPIO_PM_TO_SYS(21); /* disp power enable_n */
-	gpio43 = PM8921_GPIO_PM_TO_SYS(43); /* Displays Enable (rst_n)*/
-	gpio24 = PM8921_GPIO_PM_TO_SYS(24); /* Backlight PWM */
-
-	if (!dsi_power_on) {
-
-		reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
-				"dsi_vdda");
-		if (IS_ERR(reg_l2)) {
-			pr_err("could not get 8921_l2, rc = %ld\n",
-				PTR_ERR(reg_l2));
-			return -ENODEV;
-		}
-
-		rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
-		if (rc) {
-			pr_err("set_voltage l2 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-
-		reg_ext_3p3v = regulator_get(&msm_mipi_dsi1_device.dev,
-			"vdd_lvds_3p3v");
-		if (IS_ERR(reg_ext_3p3v)) {
-			pr_err("could not get reg_ext_3p3v, rc = %ld\n",
-			       PTR_ERR(reg_ext_3p3v));
-		    return -ENODEV;
-		}
-
-		rc = gpio_request(gpio21, "disp_pwr_en_n");
-		if (rc) {
-			pr_err("request gpio 21 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-
-		rc = gpio_request(gpio43, "disp_rst_n");
-		if (rc) {
-			pr_err("request gpio 43 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-
-		rc = gpio_request(gpio24, "disp_backlight_pwm");
-		if (rc) {
-			pr_err("request gpio 24 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-
-		dsi_power_on = true;
-	}
-
-	if (on) {
-		rc = regulator_set_optimum_mode(reg_l2, 100000);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_enable(reg_l2);
-		if (rc) {
-			pr_err("enable l2 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-
-		rc = regulator_enable(reg_ext_3p3v);
-		if (rc) {
-			pr_err("enable reg_ext_3p3v failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-
-		/* set reset pin before power enable */
-		gpio_set_value_cansleep(gpio43, 0); /* disp disable (resx=0) */
-
-		gpio_set_value_cansleep(gpio21, 0); /* disp power enable_n */
-		msleep(20);
-		gpio_set_value_cansleep(gpio43, 1); /* disp enable */
-		msleep(20);
-		gpio_set_value_cansleep(gpio43, 0); /* disp enable */
-		msleep(20);
-		gpio_set_value_cansleep(gpio43, 1); /* disp enable */
-		msleep(20);
-	} else {
-		gpio_set_value_cansleep(gpio43, 0);
-		gpio_set_value_cansleep(gpio21, 1);
-
-		rc = regulator_disable(reg_l2);
-		if (rc) {
-			pr_err("disable reg_l2 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_disable(reg_ext_3p3v);
-		if (rc) {
-			pr_err("disable reg_ext_3p3v failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_set_optimum_mode(reg_l2, 100);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-static int mipi_dsi_cdp_panel_power(int on)
-{
-	static struct regulator *reg_l8, *reg_l23, *reg_l2;
-	static int gpio43;
-	int rc;
-
-	pr_info("%s: state : %d\n", __func__, on);
-
-	if (!dsi_power_on) {
-
-		reg_l8 = regulator_get(&msm_mipi_dsi1_device.dev,
-				"dsi_vdc");
-		if (IS_ERR(reg_l8)) {
-			pr_err("could not get 8921_l8, rc = %ld\n",
-				PTR_ERR(reg_l8));
-			return -ENODEV;
-		}
-		reg_l23 = regulator_get(&msm_mipi_dsi1_device.dev,
-				"dsi_vddio");
-		if (IS_ERR(reg_l23)) {
-			pr_err("could not get 8921_l23, rc = %ld\n",
-				PTR_ERR(reg_l23));
-			return -ENODEV;
-		}
-		reg_l2 = regulator_get(&msm_mipi_dsi1_device.dev,
-				"dsi_vdda");
-		if (IS_ERR(reg_l2)) {
-			pr_err("could not get 8921_l2, rc = %ld\n",
-				PTR_ERR(reg_l2));
-			return -ENODEV;
-		}
-		rc = regulator_set_voltage(reg_l8, 2800000, 3000000);
-		if (rc) {
-			pr_err("set_voltage l8 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_set_voltage(reg_l23, 1800000, 1800000);
-		if (rc) {
-			pr_err("set_voltage l23 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_set_voltage(reg_l2, 1200000, 1200000);
-		if (rc) {
-			pr_err("set_voltage l2 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		gpio43 = PM8921_GPIO_PM_TO_SYS(43);
-		rc = gpio_request(gpio43, "disp_rst_n");
-		if (rc) {
-			pr_err("request gpio 43 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		dsi_power_on = true;
-	}
-	if (on) {
-		rc = regulator_set_optimum_mode(reg_l8, 100000);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_set_optimum_mode(reg_l23, 100000);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_set_optimum_mode(reg_l2, 100000);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_enable(reg_l8);
-		if (rc) {
-			pr_err("enable l8 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_enable(reg_l23);
-		if (rc) {
-			pr_err("enable l8 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_enable(reg_l2);
-		if (rc) {
-			pr_err("enable l2 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		gpio_set_value_cansleep(gpio43, 1);
-	} else {
-		rc = regulator_disable(reg_l2);
-		if (rc) {
-			pr_err("disable reg_l2 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_disable(reg_l8);
-		if (rc) {
-			pr_err("disable reg_l8 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_disable(reg_l23);
-		if (rc) {
-			pr_err("disable reg_l23 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_set_optimum_mode(reg_l8, 100);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l8 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_set_optimum_mode(reg_l23, 100);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_set_optimum_mode(reg_l2, 100);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l2 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		gpio_set_value_cansleep(gpio43, 0);
-	}
-	return 0;
-}
-
-static int mipi_dsi_panel_power(int on)
-{
-	int ret;
-
-	pr_info("%s: on=%d\n", __func__, on);
-
-	if (machine_is_msm8960_liquid())
-		ret = mipi_dsi_liquid_panel_power(on);
-	else
-		ret = mipi_dsi_cdp_panel_power(on);
-
-	return ret;
-}
-
-static struct mipi_dsi_platform_data mipi_dsi_pdata = {
-	.vsync_gpio = MDP_VSYNC_GPIO,
-	.dsi_power_save = mipi_dsi_panel_power,
-};
-
-#ifdef CONFIG_MSM_BUS_SCALING
-
-static struct msm_bus_vectors mdp_init_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 0,
-		.ib = 0,
-	},
-};
-
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static struct msm_bus_vectors hdmi_as_primary_vectors[] = {
-	/* If HDMI is used as primary */
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 2000000000,
-		.ib = 2000000000,
-	},
-};
-static struct msm_bus_paths mdp_bus_scale_usecases[] = {
-	{
-		ARRAY_SIZE(mdp_init_vectors),
-		mdp_init_vectors,
-	},
-	{
-		ARRAY_SIZE(hdmi_as_primary_vectors),
-		hdmi_as_primary_vectors,
-	},
-	{
-		ARRAY_SIZE(hdmi_as_primary_vectors),
-		hdmi_as_primary_vectors,
-	},
-	{
-		ARRAY_SIZE(hdmi_as_primary_vectors),
-		hdmi_as_primary_vectors,
-	},
-	{
-		ARRAY_SIZE(hdmi_as_primary_vectors),
-		hdmi_as_primary_vectors,
-	},
-	{
-		ARRAY_SIZE(hdmi_as_primary_vectors),
-		hdmi_as_primary_vectors,
-	},
-};
-#else
-static struct msm_bus_vectors mdp_ui_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 216000000 * 2,
-		.ib = 270000000 * 2,
-	},
-};
-
-static struct msm_bus_vectors mdp_vga_vectors[] = {
-	/* VGA and less video */
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 216000000 * 2,
-		.ib = 270000000 * 2,
-	},
-};
-
-static struct msm_bus_vectors mdp_720p_vectors[] = {
-	/* 720p and less video */
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 230400000 * 2,
-		.ib = 288000000 * 2,
-	},
-};
-
-static struct msm_bus_vectors mdp_1080p_vectors[] = {
-	/* 1080p and less video */
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 334080000 * 2,
-		.ib = 417600000 * 2,
-	},
-};
-
-static struct msm_bus_paths mdp_bus_scale_usecases[] = {
-	{
-		ARRAY_SIZE(mdp_init_vectors),
-		mdp_init_vectors,
-	},
-	{
-		ARRAY_SIZE(mdp_ui_vectors),
-		mdp_ui_vectors,
-	},
-	{
-		ARRAY_SIZE(mdp_ui_vectors),
-		mdp_ui_vectors,
-	},
-	{
-		ARRAY_SIZE(mdp_vga_vectors),
-		mdp_vga_vectors,
-	},
-	{
-		ARRAY_SIZE(mdp_720p_vectors),
-		mdp_720p_vectors,
-	},
-	{
-		ARRAY_SIZE(mdp_1080p_vectors),
-		mdp_1080p_vectors,
-	},
-};
-#endif
-
-static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
-	mdp_bus_scale_usecases,
-	ARRAY_SIZE(mdp_bus_scale_usecases),
-	.name = "mdp",
-};
-
-#endif
-
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-int mdp_core_clk_rate_table[] = {
-	200000000,
-	200000000,
-	200000000,
-	200000000,
-};
-#else
-int mdp_core_clk_rate_table[] = {
-	85330000,
-	85330000,
-	160000000,
-	200000000,
-};
-#endif
-
-static struct msm_panel_common_pdata mdp_pdata = {
-	.gpio = MDP_VSYNC_GPIO,
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-	.mdp_core_clk_rate = 200000000,
-#else
-	.mdp_core_clk_rate = 85330000,
-#endif
-	.mdp_core_clk_table = mdp_core_clk_rate_table,
-	.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
-#ifdef CONFIG_MSM_BUS_SCALING
-	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
-#endif
-	.mdp_rev = MDP_REV_42,
-	.writeback_offset = writeback_offset,
-};
-
-static struct platform_device mipi_dsi_renesas_panel_device = {
-	.name = "mipi_renesas",
-	.id = 0,
-};
-
-static struct platform_device mipi_dsi_simulator_panel_device = {
-	.name = "mipi_simulator",
-	.id = 0,
-};
-
-#define LPM_CHANNEL0 0
-static int toshiba_gpio[] = {LPM_CHANNEL0};
-
-static struct mipi_dsi_panel_platform_data toshiba_pdata = {
-	.gpio = toshiba_gpio,
-};
-
-static struct platform_device mipi_dsi_toshiba_panel_device = {
-	.name = "mipi_toshiba",
-	.id = 0,
-	.dev = {
-		.platform_data = &toshiba_pdata,
-	}
-};
-
-#define FPGA_3D_GPIO_CONFIG_ADDR	0xB5
-static int dsi2lvds_gpio[2] = {
-	0,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
-	0x1F08 /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
-	};
-
-static struct msm_panel_common_pdata mipi_dsi2lvds_pdata = {
-	.gpio_num = dsi2lvds_gpio,
-};
-
-static struct mipi_dsi_phy_ctrl dsi_novatek_cmd_mode_phy_db = {
-
-/* DSI_BIT_CLK at 500MHz, 2 lane, RGB888 */
-	{0x0F, 0x0a, 0x04, 0x00, 0x20},	/* regulator */
-	/* timing   */
-	{0xab, 0x8a, 0x18, 0x00, 0x92, 0x97, 0x1b, 0x8c,
-	0x0c, 0x03, 0x04, 0xa0},
-	{0x5f, 0x00, 0x00, 0x10},	/* phy ctrl */
-	{0xff, 0x00, 0x06, 0x00},	/* strength */
-	/* pll control */
-	{0x40, 0xf9, 0x30, 0xda, 0x00, 0x40, 0x03, 0x62,
-	0x40, 0x07, 0x03,
-	0x00, 0x1a, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01},
-};
-
-static struct mipi_dsi_panel_platform_data novatek_pdata = {
-	.fpga_3d_config_addr  = FPGA_3D_GPIO_CONFIG_ADDR,
-	.fpga_ctrl_mode = FPGA_SPI_INTF,
-	.phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
-};
-
-static struct platform_device mipi_dsi_novatek_panel_device = {
-	.name = "mipi_novatek",
-	.id = 0,
-	.dev = {
-		.platform_data = &novatek_pdata,
-	}
-};
-
-static struct platform_device mipi_dsi2lvds_bridge_device = {
-	.name = "mipi_tc358764",
-	.id = 0,
-	.dev.platform_data = &mipi_dsi2lvds_pdata,
-};
-
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-static struct resource hdmi_msm_resources[] = {
-	{
-		.name  = "hdmi_msm_qfprom_addr",
-		.start = 0x00700000,
-		.end   = 0x007060FF,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.name  = "hdmi_msm_hdmi_addr",
-		.start = 0x04A00000,
-		.end   = 0x04A00FFF,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.name  = "hdmi_msm_irq",
-		.start = HDMI_IRQ,
-		.end   = HDMI_IRQ,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static int hdmi_enable_5v(int on);
-static int hdmi_core_power(int on, int show);
-static int hdmi_cec_power(int on);
-
-static struct msm_hdmi_platform_data hdmi_msm_data = {
-	.irq = HDMI_IRQ,
-	.enable_5v = hdmi_enable_5v,
-	.core_power = hdmi_core_power,
-	.cec_power = hdmi_cec_power,
-};
-
-static struct platform_device hdmi_msm_device = {
-	.name = "hdmi_msm",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(hdmi_msm_resources),
-	.resource = hdmi_msm_resources,
-	.dev.platform_data = &hdmi_msm_data,
-};
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
-
-#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
-static struct platform_device wfd_panel_device = {
-	.name = "wfd_panel",
-	.id = 0,
-	.dev.platform_data = NULL,
-};
-#endif
-
-#ifdef CONFIG_MSM_BUS_SCALING
-static struct msm_bus_vectors dtv_bus_init_vectors[] = {
-	{
-		.src = MSM_BUS_MASTER_MDP_PORT0,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 0,
-		.ib = 0,
-	},
-};
-
-#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,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 566092800 * 2,
-		.ib = 707616000 * 2,
-	},
-};
-#endif
-
-static struct msm_bus_paths dtv_bus_scale_usecases[] = {
-	{
-		ARRAY_SIZE(dtv_bus_init_vectors),
-		dtv_bus_init_vectors,
-	},
-	{
-		ARRAY_SIZE(dtv_bus_def_vectors),
-		dtv_bus_def_vectors,
-	},
-};
-static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
-	dtv_bus_scale_usecases,
-	ARRAY_SIZE(dtv_bus_scale_usecases),
-	.name = "dtv",
-};
-
-static struct lcdc_platform_data dtv_pdata = {
-	.bus_scale_table = &dtv_bus_scale_pdata,
-};
-#endif
-
-static void __init msm_fb_add_devices(void)
-{
-	struct platform_device *ptr = NULL;
-
-	if (machine_is_msm8960_liquid())
-		ptr = &mipi_dsi2lvds_bridge_device;
-	else
-		ptr = &mipi_dsi_toshiba_panel_device;
-	platform_add_devices(&ptr, 1);
-
-	if (machine_is_msm8x60_rumi3()) {
-		msm_fb_register_device("mdp", NULL);
-		mipi_dsi_pdata.target_type = 1;
-	} else
-		msm_fb_register_device("mdp", &mdp_pdata);
-	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
-#ifdef CONFIG_MSM_BUS_SCALING
-	msm_fb_register_device("dtv", &dtv_pdata);
-#endif
-}
-
-static struct gpiomux_setting mdp_vsync_suspend_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting mdp_vsync_active_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_mdp_vsync_configs[] __initdata = {
-	{
-		.gpio = MDP_VSYNC_GPIO,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &mdp_vsync_active_cfg,
-			[GPIOMUX_SUSPENDED] = &mdp_vsync_suspend_cfg,
-		},
-	}
-};
-
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-static struct gpiomux_setting hdmi_suspend_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting hdmi_active_1_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
-static struct gpiomux_setting hdmi_active_2_cfg = {
-	.func = GPIOMUX_FUNC_1,
-	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct msm_gpiomux_config msm8960_hdmi_configs[] __initdata = {
-	{
-		.gpio = 99,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
-			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
-		},
-	},
-	{
-		.gpio = 100,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
-			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
-		},
-	},
-	{
-		.gpio = 101,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &hdmi_active_1_cfg,
-			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
-		},
-	},
-	{
-		.gpio = 102,
-		.settings = {
-			[GPIOMUX_ACTIVE]    = &hdmi_active_2_cfg,
-			[GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
-		},
-	},
-};
-
-static int hdmi_enable_5v(int on)
-{
-	/* TBD: PM8921 regulator instead of 8901 */
-	static struct regulator *reg_8921_hdmi_mvs;	/* HDMI_5V */
-	static int prev_on;
-	int rc;
-
-	if (on == prev_on)
-		return 0;
-
-	if (!reg_8921_hdmi_mvs)
-		reg_8921_hdmi_mvs = regulator_get(&hdmi_msm_device.dev,
-			"hdmi_mvs");
-
-	if (on) {
-		rc = regulator_enable(reg_8921_hdmi_mvs);
-		if (rc) {
-			pr_err("'%s' regulator enable failed, rc=%d\n",
-				"8921_hdmi_mvs", rc);
-			return rc;
-		}
-		pr_debug("%s(on): success\n", __func__);
-	} else {
-		rc = regulator_disable(reg_8921_hdmi_mvs);
-		if (rc)
-			pr_warning("'%s' regulator disable failed, rc=%d\n",
-				"8921_hdmi_mvs", rc);
-		pr_debug("%s(off): success\n", __func__);
-	}
-
-	prev_on = on;
-
-	return 0;
-}
-
-static int hdmi_core_power(int on, int show)
-{
-	static struct regulator *reg_8921_l23, *reg_8921_s4;
-	static int prev_on;
-	int rc;
-
-	if (on == prev_on)
-		return 0;
-
-	/* TBD: PM8921 regulator instead of 8901 */
-	if (!reg_8921_l23) {
-		reg_8921_l23 = regulator_get(&hdmi_msm_device.dev, "hdmi_avdd");
-		if (IS_ERR(reg_8921_l23)) {
-			pr_err("could not get reg_8921_l23, rc = %ld\n",
-				PTR_ERR(reg_8921_l23));
-			return -ENODEV;
-		}
-		rc = regulator_set_voltage(reg_8921_l23, 1800000, 1800000);
-		if (rc) {
-			pr_err("set_voltage failed for 8921_l23, rc=%d\n", rc);
-			return -EINVAL;
-		}
-	}
-	if (!reg_8921_s4) {
-		reg_8921_s4 = regulator_get(&hdmi_msm_device.dev, "hdmi_vcc");
-		if (IS_ERR(reg_8921_s4)) {
-			pr_err("could not get reg_8921_s4, rc = %ld\n",
-				PTR_ERR(reg_8921_s4));
-			return -ENODEV;
-		}
-		rc = regulator_set_voltage(reg_8921_s4, 1800000, 1800000);
-		if (rc) {
-			pr_err("set_voltage failed for 8921_s4, rc=%d\n", rc);
-			return -EINVAL;
-		}
-	}
-
-	if (on) {
-		rc = regulator_set_optimum_mode(reg_8921_l23, 100000);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		rc = regulator_enable(reg_8921_l23);
-		if (rc) {
-			pr_err("'%s' regulator enable failed, rc=%d\n",
-				"hdmi_avdd", rc);
-			return rc;
-		}
-		rc = regulator_enable(reg_8921_s4);
-		if (rc) {
-			pr_err("'%s' regulator enable failed, rc=%d\n",
-				"hdmi_vcc", rc);
-			return rc;
-		}
-		rc = gpio_request(100, "HDMI_DDC_CLK");
-		if (rc) {
-			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
-				"HDMI_DDC_CLK", 100, rc);
-			goto error1;
-		}
-		rc = gpio_request(101, "HDMI_DDC_DATA");
-		if (rc) {
-			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
-				"HDMI_DDC_DATA", 101, rc);
-			goto error2;
-		}
-		rc = gpio_request(102, "HDMI_HPD");
-		if (rc) {
-			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
-				"HDMI_HPD", 102, rc);
-			goto error3;
-		}
-		pr_debug("%s(on): success\n", __func__);
-	} else {
-		gpio_free(100);
-		gpio_free(101);
-		gpio_free(102);
-
-		rc = regulator_disable(reg_8921_l23);
-		if (rc) {
-			pr_err("disable reg_8921_l23 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_disable(reg_8921_s4);
-		if (rc) {
-			pr_err("disable reg_8921_s4 failed, rc=%d\n", rc);
-			return -ENODEV;
-		}
-		rc = regulator_set_optimum_mode(reg_8921_l23, 100);
-		if (rc < 0) {
-			pr_err("set_optimum_mode l23 failed, rc=%d\n", rc);
-			return -EINVAL;
-		}
-		pr_debug("%s(off): success\n", __func__);
-	}
-
-	prev_on = on;
-
-	return 0;
-
-error3:
-	gpio_free(101);
-error2:
-	gpio_free(100);
-error1:
-	regulator_disable(reg_8921_l23);
-	regulator_disable(reg_8921_s4);
-	return rc;
-}
-
-static int hdmi_cec_power(int on)
-{
-	static int prev_on;
-	int rc;
-
-	if (on == prev_on)
-		return 0;
-
-	if (on) {
-		rc = gpio_request(99, "HDMI_CEC_VAR");
-		if (rc) {
-			pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
-				"HDMI_CEC_VAR", 99, rc);
-			goto error;
-		}
-		pr_debug("%s(on): success\n", __func__);
-	} else {
-		gpio_free(99);
-		pr_debug("%s(off): success\n", __func__);
-	}
-
-	prev_on = on;
-
-	return 0;
-error:
-	return rc;
-}
-#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
-
-static void __init msm8960_allocate_memory_regions(void)
-{
-	void *addr;
-	unsigned long size;
-
-	size = MSM_FB_SIZE;
-	addr = alloc_bootmem_align(size, 0x1000);
-	msm_fb_resources[0].start = __pa(addr);
-	msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
-	pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
-			size, addr, __pa(addr));
-
-}
-#ifdef CONFIG_WCD9310_CODEC
-
-#define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_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 tabla_pdata tabla_platform_data = {
-	.slimbus_slave_device = {
-		.name = "tabla-slave",
-		.e_addr = {0, 0, 0x10, 0, 0x17, 2},
-	},
-	.irq = MSM_GPIO_TO_INT(62),
-	.irq_base = TABLA_INTERRUPT_BASE,
-	.num_irqs = NR_TABLA_IRQS,
-	.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
-	.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,
-	}
-};
-
-static struct slim_device msm_slim_tabla = {
-	.name = "tabla-slim",
-	.e_addr = {0, 1, 0x10, 0, 0x17, 2},
-	.dev = {
-		.platform_data = &tabla_platform_data,
-	},
-};
-
-static struct tabla_pdata tabla20_platform_data = {
-	.slimbus_slave_device = {
-		.name = "tabla-slave",
-		.e_addr = {0, 0, 0x60, 0, 0x17, 2},
-	},
-	.irq = MSM_GPIO_TO_INT(62),
-	.irq_base = TABLA_INTERRUPT_BASE,
-	.num_irqs = NR_TABLA_IRQS,
-	.reset_gpio = PM8921_GPIO_PM_TO_SYS(34),
-	.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,
-	}
-};
-
-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[] = {
-#ifdef CONFIG_WCD9310_CODEC
-	{
-		.bus_num = 1,
-		.slim_slave = &msm_slim_tabla,
-	},
-	{
-		.bus_num = 1,
-		.slim_slave = &msm_slim_tabla20,
-	},
-#endif
-	/* add more slimbus slaves as needed */
-};
-
-#define MSM_WCNSS_PHYS	0x03000000
-#define MSM_WCNSS_SIZE	0x280000
-
-static struct resource resources_wcnss_wlan[] = {
-	{
-		.start	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
-		.end	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
-		.name	= "wcnss_wlanrx_irq",
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
-		.end	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
-		.name	= "wcnss_wlantx_irq",
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= MSM_WCNSS_PHYS,
-		.end	= MSM_WCNSS_PHYS + MSM_WCNSS_SIZE - 1,
-		.name	= "wcnss_mmio",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= 84,
-		.end	= 88,
-		.name	= "wcnss_gpios_5wire",
-		.flags	= IORESOURCE_IO,
-	},
-};
-
-static struct qcom_wcnss_opts qcom_wcnss_pdata = {
-	.has_48mhz_xo	= 1,
-};
-
-static struct platform_device msm_device_wcnss_wlan = {
-	.name		= "wcnss_wlan",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(resources_wcnss_wlan),
-	.resource	= resources_wcnss_wlan,
-	.dev		= {.platform_data = &qcom_wcnss_pdata},
-};
-
-#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
-		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
-		defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
-		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
-
-#define QCE_SIZE		0x10000
-#define QCE_0_BASE		0x18500000
-
-#define QCE_HW_KEY_SUPPORT	0
-#define QCE_SHA_HMAC_SUPPORT	1
-#define QCE_SHARE_CE_RESOURCE	1
-#define QCE_CE_SHARED		0
-
-static struct resource qcrypto_resources[] = {
-	[0] = {
-		.start = QCE_0_BASE,
-		.end = QCE_0_BASE + QCE_SIZE - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.name = "crypto_channels",
-		.start = DMOV_CE_IN_CHAN,
-		.end = DMOV_CE_OUT_CHAN,
-		.flags = IORESOURCE_DMA,
-	},
-	[2] = {
-		.name = "crypto_crci_in",
-		.start = DMOV_CE_IN_CRCI,
-		.end = DMOV_CE_IN_CRCI,
-		.flags = IORESOURCE_DMA,
-	},
-	[3] = {
-		.name = "crypto_crci_out",
-		.start = DMOV_CE_OUT_CRCI,
-		.end = DMOV_CE_OUT_CRCI,
-		.flags = IORESOURCE_DMA,
-	},
-};
-
-static struct resource qcedev_resources[] = {
-	[0] = {
-		.start = QCE_0_BASE,
-		.end = QCE_0_BASE + QCE_SIZE - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.name = "crypto_channels",
-		.start = DMOV_CE_IN_CHAN,
-		.end = DMOV_CE_OUT_CHAN,
-		.flags = IORESOURCE_DMA,
-	},
-	[2] = {
-		.name = "crypto_crci_in",
-		.start = DMOV_CE_IN_CRCI,
-		.end = DMOV_CE_IN_CRCI,
-		.flags = IORESOURCE_DMA,
-	},
-	[3] = {
-		.name = "crypto_crci_out",
-		.start = DMOV_CE_OUT_CRCI,
-		.end = DMOV_CE_OUT_CRCI,
-		.flags = IORESOURCE_DMA,
-	},
-};
-
-#endif
-
-#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
-		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
-
-static struct msm_ce_hw_support qcrypto_ce_hw_suppport = {
-	.ce_shared = QCE_CE_SHARED,
-	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
-	.hw_key_support = QCE_HW_KEY_SUPPORT,
-	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
-};
-
-static struct platform_device qcrypto_device = {
-	.name		= "qcrypto",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(qcrypto_resources),
-	.resource	= qcrypto_resources,
-	.dev		= {
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &qcrypto_ce_hw_suppport,
-	},
-};
-#endif
-
-#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
-		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
-
-static struct msm_ce_hw_support qcedev_ce_hw_suppport = {
-	.ce_shared = QCE_CE_SHARED,
-	.shared_ce_resource = QCE_SHARE_CE_RESOURCE,
-	.hw_key_support = QCE_HW_KEY_SUPPORT,
-	.sha_hmac = QCE_SHA_HMAC_SUPPORT,
-};
-
-static struct platform_device qcedev_device = {
-	.name		= "qce",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(qcedev_resources),
-	.resource	= qcedev_resources,
-	.dev		= {
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &qcedev_ce_hw_suppport,
-	},
-};
-#endif
-
-#define MDM2AP_ERRFATAL			70
-#define AP2MDM_ERRFATAL			95
-#define MDM2AP_STATUS			69
-#define AP2MDM_STATUS			94
-#define AP2MDM_PMIC_RESET_N		80
-#define AP2MDM_KPDPWR_N			81
-
-static struct gpiomux_setting ap2mdm_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting mdm2ap_status_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct gpiomux_setting mdm2ap_errfatal_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_16MA,
-	.pull = GPIOMUX_PULL_DOWN,
-};
-
-static struct gpiomux_setting ap2mdm_kpdpwr_n_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_NONE,
-};
-
-static struct msm_gpiomux_config mdm_configs[] __initdata = {
-	/* AP2MDM_STATUS */
-	{
-		.gpio = AP2MDM_STATUS,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
-		}
-	},
-	/* MDM2AP_STATUS */
-	{
-		.gpio = MDM2AP_STATUS,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
-		}
-	},
-	/* MDM2AP_ERRFATAL */
-	{
-		.gpio = MDM2AP_ERRFATAL,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
-		}
-	},
-	/* AP2MDM_ERRFATAL */
-	{
-		.gpio = AP2MDM_ERRFATAL,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
-		}
-	},
-	/* AP2MDM_KPDPWR_N */
-	{
-		.gpio = AP2MDM_KPDPWR_N,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
-		}
-	},
-	/* AP2MDM_PMIC_RESET_N */
-	{
-		.gpio = AP2MDM_PMIC_RESET_N,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &ap2mdm_kpdpwr_n_cfg,
-		}
-	}
-};
-
-static struct resource mdm_resources[] = {
-	{
-		.start	= MDM2AP_ERRFATAL,
-		.end	= MDM2AP_ERRFATAL,
-		.name	= "MDM2AP_ERRFATAL",
-		.flags	= IORESOURCE_IO,
-	},
-	{
-		.start	= AP2MDM_ERRFATAL,
-		.end	= AP2MDM_ERRFATAL,
-		.name	= "AP2MDM_ERRFATAL",
-		.flags	= IORESOURCE_IO,
-	},
-	{
-		.start	= MDM2AP_STATUS,
-		.end	= MDM2AP_STATUS,
-		.name	= "MDM2AP_STATUS",
-		.flags	= IORESOURCE_IO,
-	},
-	{
-		.start	= AP2MDM_STATUS,
-		.end	= AP2MDM_STATUS,
-		.name	= "AP2MDM_STATUS",
-		.flags	= IORESOURCE_IO,
-	},
-	{
-		.start	= AP2MDM_PMIC_RESET_N,
-		.end	= AP2MDM_PMIC_RESET_N,
-		.name	= "AP2MDM_PMIC_RESET_N",
-		.flags	= IORESOURCE_IO,
-	},
-	{
-		.start	= AP2MDM_KPDPWR_N,
-		.end	= AP2MDM_KPDPWR_N,
-		.name	= "AP2MDM_KPDPWR_N",
-		.flags	= IORESOURCE_IO,
-	},
-};
-
-static struct mdm_platform_data mdm_platform_data = {
-	.mdm_version = "2.5",
-};
-
-struct platform_device mdm_device = {
-	.name		= "mdm2_modem",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(mdm_resources),
-	.resource	= mdm_resources,
-	.dev		= {
-		.platform_data = &mdm_platform_data,
-	},
-};
-
-static struct platform_device *mdm_devices[] __initdata = {
-	&mdm_device,
-};
-
-static int __init gpiomux_init(void)
-{
-	int rc;
-
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
-	if (rc) {
-		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
-		return rc;
-	}
-
-	msm_gpiomux_install(msm8960_cam_common_configs,
-			ARRAY_SIZE(msm8960_cam_common_configs));
-
-	msm_gpiomux_install(msm8960_gpiomux_configs,
-			ARRAY_SIZE(msm8960_gpiomux_configs));
-
-	msm_gpiomux_install(msm8960_gsbi_configs,
-			ARRAY_SIZE(msm8960_gsbi_configs));
-
-	msm_gpiomux_install(msm8960_cyts_configs,
-			ARRAY_SIZE(msm8960_cyts_configs));
-
-	msm_gpiomux_install(msm8960_slimbus_config,
-			ARRAY_SIZE(msm8960_slimbus_config));
-
-	msm_gpiomux_install(msm8960_audio_codec_configs,
-			ARRAY_SIZE(msm8960_audio_codec_configs));
-
-	msm_gpiomux_install(msm8960_audio_auxpcm_configs,
-			ARRAY_SIZE(msm8960_audio_auxpcm_configs));
-
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-	msm_gpiomux_install(msm8960_hdmi_configs,
-			ARRAY_SIZE(msm8960_hdmi_configs));
-#endif
-
-	msm_gpiomux_install(msm8960_mdp_vsync_configs,
-			ARRAY_SIZE(msm8960_mdp_vsync_configs));
-
-	msm_gpiomux_install(wcnss_5wire_interface,
-			ARRAY_SIZE(wcnss_5wire_interface));
-
-	if (machine_is_msm8960_mtp() || machine_is_msm8960_fluid() ||
-		machine_is_msm8960_liquid() || machine_is_msm8960_cdp())
-		msm_gpiomux_install(hap_lvl_shft_config,
-			ARRAY_SIZE(hap_lvl_shft_config));
-
-	if (PLATFORM_IS_CHARM25())
-		msm_gpiomux_install(mdm_configs,
-			ARRAY_SIZE(mdm_configs));
-
-	return 0;
-}
-
-#define MSM_SHARED_RAM_PHYS 0x80000000
-
-static struct pm8xxx_adc_amux pm8xxx_adc_channels_data[] = {
-	{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
-	{"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
-	{"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
-	{"pa_therm1", ADC_MPP_1_AMUX8, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
-	{"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
-	{"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
-		ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
-};
-
-static struct pm8xxx_adc_properties pm8xxx_adc_data = {
-	.adc_vdd_reference	= 1800, /* milli-voltage for this adc */
-	.bitresolution		= 15,
-	.bipolar                = 0,
-};
-
-static struct pm8xxx_adc_platform_data pm8xxx_adc_pdata = {
-	.adc_channel		= pm8xxx_adc_channels_data,
-	.adc_num_board_channel	= ARRAY_SIZE(pm8xxx_adc_channels_data),
-	.adc_prop		= &pm8xxx_adc_data,
-	.adc_mpp_base		= PM8921_MPP_PM_TO_SYS(1),
-};
-
-static void __init msm8960_map_io(void)
-{
-	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
-	msm_map_msm8960_io();
-
-	if (socinfo_init() < 0)
-		pr_err("socinfo_init() failed!\n");
-}
-
-#ifdef CONFIG_ARCH_MSM8930
-static void __init msm8930_map_io(void)
-{
-	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
-	msm_map_msm8930_io();
-
-	if (socinfo_init() < 0)
-		pr_err("socinfo_init() failed!\n");
-}
-#endif
-
-static void __init msm8960_init_irq(void)
-{
-	unsigned int i;
-
-	msm_mpm_irq_extn_init();
-	gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
-						(void *)MSM_QGIC_CPU_BASE);
-
-	/* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
-	writel_relaxed(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
-
-	writel_relaxed(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
-	mb();
-
-	/* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
-	 * as they are configured as level, which does not play nice with
-	 * handle_percpu_irq.
-	 */
-	for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
-		if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
-			irq_set_handler(i, handle_percpu_irq);
-	}
-}
-
-/* MSM8960 has 5 SDCC controllers */
-enum sdcc_controllers {
-	SDCC1,
-	SDCC2,
-	SDCC3,
-	SDCC4,
-	SDCC5,
-	MAX_SDCC_CONTROLLER
-};
-
-/* All SDCC controllers require VDD/VCC voltage */
-static struct msm_mmc_reg_data mmc_vdd_reg_data[MAX_SDCC_CONTROLLER] = {
-	/* SDCC1 : eMMC card connected */
-	[SDCC1] = {
-		.name = "sdc_vdd",
-		.high_vol_level = 2950000,
-		.low_vol_level = 2950000,
-		.always_on = 1,
-		.lpm_sup = 1,
-		.lpm_uA = 9000,
-		.hpm_uA = 200000, /* 200mA */
-	},
-	/* SDCC3 : External card slot connected */
-	[SDCC3] = {
-		.name = "sdc_vdd",
-		.high_vol_level = 2950000,
-		.low_vol_level = 2950000,
-		.hpm_uA = 600000, /* 600mA */
-	}
-};
-
-/* Only slots having eMMC card will require VCCQ voltage */
-static struct msm_mmc_reg_data mmc_vccq_reg_data[1] = {
-	/* SDCC1 : eMMC card connected */
-	[SDCC1] = {
-		.name = "sdc_vccq",
-		.always_on = 1,
-		.high_vol_level = 1800000,
-		.low_vol_level = 1800000,
-		.hpm_uA = 200000, /* 200mA */
-	}
-};
-
-/* All SDCC controllers may require voting for VDD PAD voltage */
-static struct msm_mmc_reg_data mmc_vddp_reg_data[MAX_SDCC_CONTROLLER] = {
-	/* SDCC3 : External card slot connected */
-	[SDCC3] = {
-		.name = "sdc_vddp",
-		.high_vol_level = 2950000,
-		.low_vol_level = 1850000,
-		.always_on = 1,
-		.lpm_sup = 1,
-		/* Max. Active current required is 16 mA */
-		.hpm_uA = 16000,
-		/*
-		 * Sleep current required is ~300 uA. But min. vote can be
-		 * in terms of mA (min. 1 mA). So let's vote for 2 mA
-		 * during sleep.
-		 */
-		.lpm_uA = 2000,
-	}
-};
-
-static struct msm_mmc_slot_reg_data mmc_slot_vreg_data[MAX_SDCC_CONTROLLER] = {
-	/* SDCC1 : eMMC card connected */
-	[SDCC1] = {
-		.vdd_data = &mmc_vdd_reg_data[SDCC1],
-		.vccq_data = &mmc_vccq_reg_data[SDCC1],
-	},
-	/* SDCC3 : External card slot connected */
-	[SDCC3] = {
-		.vdd_data = &mmc_vdd_reg_data[SDCC3],
-		.vddp_data = &mmc_vddp_reg_data[SDCC3],
-	}
-};
-
-/* SDC1 pad data */
-static struct msm_mmc_pad_drv sdc1_pad_drv_on_cfg[] = {
-	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_16MA},
-	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_10MA},
-	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_10MA}
-};
-
-static struct msm_mmc_pad_drv sdc1_pad_drv_off_cfg[] = {
-	{TLMM_HDRV_SDC1_CLK, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC1_CMD, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC1_DATA, GPIO_CFG_2MA}
-};
-
-static struct msm_mmc_pad_pull sdc1_pad_pull_on_cfg[] = {
-	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
-	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
-	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
-};
-
-static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
-	{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
-	{TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
-	{TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
-};
-
-/* SDC3 pad data */
-static struct msm_mmc_pad_drv sdc3_pad_drv_on_cfg[] = {
-	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
-	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
-	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
-};
-
-static struct msm_mmc_pad_drv sdc3_pad_drv_off_cfg[] = {
-	{TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
-	{TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
-};
-
-static struct msm_mmc_pad_pull sdc3_pad_pull_on_cfg[] = {
-	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
-	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
-	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
-};
-
-static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
-	{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
-	/*
-	 * SDC3 CMD line should be PULLed UP otherwise fluid platform will
-	 * see transitions (1 -> 0 and 0 -> 1) on card detection line,
-	 * which would result in false card detection interrupts.
-	 */
-	{TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
-	/*
-	 * Keeping DATA lines status to PULL UP will make sure that
-	 * there is no current leak during sleep if external pull up
-	 * is connected to DATA lines.
-	 */
-	{TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
-};
-
-struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.on = sdc1_pad_pull_on_cfg,
-		.off = sdc1_pad_pull_off_cfg,
-		.size = ARRAY_SIZE(sdc1_pad_pull_on_cfg)
-	},
-	[SDCC3] = {
-		.on = sdc3_pad_pull_on_cfg,
-		.off = sdc3_pad_pull_off_cfg,
-		.size = ARRAY_SIZE(sdc3_pad_pull_on_cfg)
-	},
-};
-
-struct msm_mmc_pad_drv_data mmc_pad_drv_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.on = sdc1_pad_drv_on_cfg,
-		.off = sdc1_pad_drv_off_cfg,
-		.size = ARRAY_SIZE(sdc1_pad_drv_on_cfg)
-	},
-	[SDCC3] = {
-		.on = sdc3_pad_drv_on_cfg,
-		.off = sdc3_pad_drv_off_cfg,
-		.size = ARRAY_SIZE(sdc3_pad_drv_on_cfg)
-	},
-};
-
-struct msm_mmc_pad_data mmc_pad_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.pull = &mmc_pad_pull_data[SDCC1],
-		.drv = &mmc_pad_drv_data[SDCC1]
-	},
-	[SDCC3] = {
-		.pull = &mmc_pad_pull_data[SDCC3],
-		.drv = &mmc_pad_drv_data[SDCC3]
-	},
-};
-
-struct msm_mmc_pin_data mmc_slot_pin_data[MAX_SDCC_CONTROLLER] = {
-	[SDCC1] = {
-		.pad_data = &mmc_pad_data[SDCC1],
-	},
-	[SDCC3] = {
-		.pad_data = &mmc_pad_data[SDCC3],
-	},
-};
-
-static unsigned int sdc1_sup_clk_rates[] = {
-	400000, 24000000, 48000000
-};
-
-static unsigned int sdc3_sup_clk_rates[] = {
-	400000, 24000000, 48000000, 96000000
-};
-
-#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
-static struct mmc_platform_data msm8960_sdc1_data = {
-	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
-#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
-	.mmc_bus_width  = MMC_CAP_8_BIT_DATA,
-#else
-	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
-#endif
-	.sup_clk_table	= sdc1_sup_clk_rates,
-	.sup_clk_cnt	= ARRAY_SIZE(sdc1_sup_clk_rates),
-	.pclk_src_dfab	= 1,
-	.nonremovable	= 1,
-	.vreg_data	= &mmc_slot_vreg_data[SDCC1],
-	.pin_data	= &mmc_slot_pin_data[SDCC1]
-};
-#endif
-
-#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
-static struct mmc_platform_data msm8960_sdc3_data = {
-	.ocr_mask       = MMC_VDD_27_28 | MMC_VDD_28_29,
-	.mmc_bus_width  = MMC_CAP_4_BIT_DATA,
-	.sup_clk_table	= sdc3_sup_clk_rates,
-	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
-	.pclk_src_dfab	= 1,
-#ifdef CONFIG_MMC_MSM_SDC3_WP_SUPPORT
-	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
-#endif
-	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
-	.pin_data	= &mmc_slot_pin_data[SDCC3],
-#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
-	.status_gpio	= PM8921_GPIO_PM_TO_SYS(26),
-	.status_irq	= PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
-	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-#endif
-	.xpc_cap	= 1,
-	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
-			MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
-			MMC_CAP_MAX_CURRENT_600)
-};
-#endif
-
-static void __init msm8960_init_mmc(void)
-{
-#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
-	/* SDC1 : eMMC card connected */
-	msm_add_sdcc(1, &msm8960_sdc1_data);
-#endif
-#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
-	/* SDC3: External card slot */
-	msm_add_sdcc(3, &msm8960_sdc3_data);
-#endif
-}
-
-static void __init msm8960_init_buses(void)
-{
-#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;
-#endif
-}
-
-static struct msm_spi_platform_data msm8960_qup_spi_gsbi1_pdata = {
-	.max_clock_speed = 15060000,
-};
-
-#ifdef CONFIG_USB_MSM_OTG_72K
-static struct msm_otg_platform_data msm_otg_pdata;
-#else
-#define USB_5V_EN		42
-static void msm_hsusb_vbus_power(bool on)
-{
-	int rc;
-	static bool vbus_is_on;
-	static struct regulator *mvs_otg_switch;
-
-	if (vbus_is_on == on)
-		return;
-
-	if (on) {
-		mvs_otg_switch = regulator_get(&msm8960_device_otg.dev,
-					       "vbus_otg");
-		if (IS_ERR(mvs_otg_switch)) {
-			pr_err("Unable to get mvs_otg_switch\n");
-			return;
-		}
-
-		rc = gpio_request(PM8921_GPIO_PM_TO_SYS(USB_5V_EN),
-						"usb_5v_en");
-		if (rc < 0) {
-			pr_err("failed to request usb_5v_en gpio\n");
-			goto put_mvs_otg;
-		}
-
-		rc = gpio_direction_output(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 1);
-		if (rc) {
-			pr_err("%s: unable to set_direction for gpio [%d]\n",
-				__func__, PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
-			goto free_usb_5v_en;
-		}
-
-		if (regulator_enable(mvs_otg_switch)) {
-			pr_err("unable to enable mvs_otg_switch\n");
-			goto err_ldo_gpio_set_dir;
-		}
-
-		vbus_is_on = true;
-		return;
-	}
-	regulator_disable(mvs_otg_switch);
-err_ldo_gpio_set_dir:
-	gpio_set_value(PM8921_GPIO_PM_TO_SYS(USB_5V_EN), 0);
-free_usb_5v_en:
-	gpio_free(PM8921_GPIO_PM_TO_SYS(USB_5V_EN));
-put_mvs_otg:
-	regulator_put(mvs_otg_switch);
-	vbus_is_on = false;
-}
-
-static struct msm_otg_platform_data msm_otg_pdata = {
-	.mode			= USB_OTG,
-	.otg_control		= OTG_PMIC_CONTROL,
-	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
-	.pclk_src_name		= "dfab_usb_hs_clk",
-	.pmic_id_irq		= PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
-	.vbus_power		= msm_hsusb_vbus_power,
-	.power_budget		= 750,
-};
-#endif
-
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-#define HSIC_HUB_RESET_GPIO	91
-static struct msm_hsic_host_platform_data msm_hsic_pdata = {
-	.strobe		= 150,
-	.data		= 151,
-};
-#else
-static struct msm_hsic_host_platform_data msm_hsic_pdata;
-#endif
-
-#define PID_MAGIC_ID		0x71432909
-#define SERIAL_NUM_MAGIC_ID	0x61945374
-#define SERIAL_NUMBER_LENGTH	127
-#define DLOAD_USB_BASE_ADD	0x2A03F0C8
-
-struct magic_num_struct {
-	uint32_t pid;
-	uint32_t serial_num;
-};
-
-struct dload_struct {
-	uint32_t	reserved1;
-	uint32_t	reserved2;
-	uint32_t	reserved3;
-	uint16_t	reserved4;
-	uint16_t	pid;
-	char		serial_number[SERIAL_NUMBER_LENGTH];
-	uint16_t	reserved5;
-	struct magic_num_struct magic_struct;
-};
-
-static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
-{
-	struct dload_struct __iomem *dload = 0;
-
-	dload = ioremap(DLOAD_USB_BASE_ADD, sizeof(*dload));
-	if (!dload) {
-		pr_err("%s: cannot remap I/O memory region: %08x\n",
-					__func__, DLOAD_USB_BASE_ADD);
-		return -ENXIO;
-	}
-
-	pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
-				__func__, dload, pid, snum);
-	/* update pid */
-	dload->magic_struct.pid = PID_MAGIC_ID;
-	dload->pid = pid;
-
-	/* update serial number */
-	dload->magic_struct.serial_num = 0;
-	if (!snum) {
-		memset(dload->serial_number, 0, SERIAL_NUMBER_LENGTH);
-		goto out;
-	}
-
-	dload->magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
-	strlcpy(dload->serial_number, snum, SERIAL_NUMBER_LENGTH);
-out:
-	iounmap(dload);
-	return 0;
-}
-
-static struct android_usb_platform_data android_usb_pdata = {
-	.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
-};
-
-static struct platform_device android_usb_device = {
-	.name	= "android_usb",
-	.id	= -1,
-	.dev	= {
-		.platform_data = &android_usb_pdata,
-	},
-};
-
-static uint8_t spm_wfi_cmd_sequence[] __initdata = {
-			0x03, 0x0f,
-};
-
-static uint8_t spm_power_collapse_without_rpm[] __initdata = {
-			0x00, 0x24, 0x54, 0x10,
-			0x09, 0x03, 0x01,
-			0x10, 0x54, 0x30, 0x0C,
-			0x24, 0x30, 0x0f,
-};
-
-static uint8_t spm_power_collapse_with_rpm[] __initdata = {
-			0x00, 0x24, 0x54, 0x10,
-			0x09, 0x07, 0x01, 0x0B,
-			0x10, 0x54, 0x30, 0x0C,
-			0x24, 0x30, 0x0f,
-};
-
-static struct msm_spm_seq_entry msm_spm_seq_list[] __initdata = {
-	[0] = {
-		.mode = MSM_SPM_MODE_CLOCK_GATING,
-		.notify_rpm = false,
-		.cmd = spm_wfi_cmd_sequence,
-	},
-	[1] = {
-		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
-		.notify_rpm = false,
-		.cmd = spm_power_collapse_without_rpm,
-	},
-	[2] = {
-		.mode = MSM_SPM_MODE_POWER_COLLAPSE,
-		.notify_rpm = true,
-		.cmd = spm_power_collapse_with_rpm,
-	},
-};
-
-static struct msm_spm_platform_data msm_spm_data[] __initdata = {
-	[0] = {
-		.reg_base_addr = MSM_SAW0_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
-		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
-#if defined(CONFIG_MSM_AVS_HW)
-		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
-		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
-#endif
-		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
-		.vctl_timeout_us = 50,
-		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
-		.modes = msm_spm_seq_list,
-	},
-	[1] = {
-		.reg_base_addr = MSM_SAW1_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
-		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
-#if defined(CONFIG_MSM_AVS_HW)
-		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
-		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
-#endif
-		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x0060009C,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x0000001C,
-		.vctl_timeout_us = 50,
-		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
-		.modes = msm_spm_seq_list,
-	},
-};
-
-static uint8_t l2_spm_wfi_cmd_sequence[] __initdata = {
-			0x00, 0x20, 0x03, 0x20,
-			0x00, 0x0f,
-};
-
-static uint8_t l2_spm_gdhs_cmd_sequence[] __initdata = {
-			0x00, 0x20, 0x34, 0x64,
-			0x48, 0x07, 0x48, 0x20,
-			0x50, 0x64, 0x04, 0x34,
-			0x50, 0x0f,
-};
-static uint8_t l2_spm_power_off_cmd_sequence[] __initdata = {
-			0x00, 0x10, 0x34, 0x64,
-			0x48, 0x07, 0x48, 0x10,
-			0x50, 0x64, 0x04, 0x34,
-			0x50, 0x0F,
-};
-
-static struct msm_spm_seq_entry msm_spm_l2_seq_list[] __initdata = {
-	[0] = {
-		.mode = MSM_SPM_L2_MODE_RETENTION,
-		.notify_rpm = false,
-		.cmd = l2_spm_wfi_cmd_sequence,
-	},
-	[1] = {
-		.mode = MSM_SPM_L2_MODE_GDHS,
-		.notify_rpm = true,
-		.cmd = l2_spm_gdhs_cmd_sequence,
-	},
-	[2] = {
-		.mode = MSM_SPM_L2_MODE_POWER_COLLAPSE,
-		.notify_rpm = true,
-		.cmd = l2_spm_power_off_cmd_sequence,
-	},
-};
-
-
-static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
-	[0] = {
-		.reg_base_addr = MSM_SAW_L2_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
-		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
-		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_1] = 0x00A00020,
-		.modes = msm_spm_l2_seq_list,
-		.num_modes = ARRAY_SIZE(msm_spm_l2_seq_list),
-	},
-};
-
-#define PM_HAP_EN_GPIO		PM8921_GPIO_PM_TO_SYS(33)
-#define PM_HAP_LEN_GPIO		PM8921_GPIO_PM_TO_SYS(20)
-
-static struct msm_xo_voter *xo_handle_d1;
-
-static int isa1200_power(int on)
-{
-	int rc = 0;
-
-	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, !!on);
-
-	rc = on ? msm_xo_mode_vote(xo_handle_d1, MSM_XO_MODE_ON) :
-			msm_xo_mode_vote(xo_handle_d1, MSM_XO_MODE_OFF);
-	if (rc < 0) {
-		pr_err("%s: failed to %svote for TCXO D1 buffer%d\n",
-				__func__, on ? "" : "de-", rc);
-		goto err_xo_vote;
-	}
-
-	return 0;
-
-err_xo_vote:
-	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, !on);
-	return rc;
-}
-
-static int isa1200_dev_setup(bool enable)
-{
-	int rc = 0;
-
-	struct pm_gpio hap_gpio_config = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.out_strength   = PM_GPIO_STRENGTH_HIGH,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.inv_int_pol    = 0,
-		.vin_sel        = 2,
-		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-		.output_value   = 0,
-	};
-
-	if (enable == true) {
-		rc = pm8xxx_gpio_config(PM_HAP_EN_GPIO, &hap_gpio_config);
-		if (rc) {
-			pr_err("%s: pm8921 gpio %d config failed(%d)\n",
-					__func__, PM_HAP_EN_GPIO, rc);
-			return rc;
-		}
-
-		rc = pm8xxx_gpio_config(PM_HAP_LEN_GPIO, &hap_gpio_config);
-		if (rc) {
-			pr_err("%s: pm8921 gpio %d config failed(%d)\n",
-					__func__, PM_HAP_LEN_GPIO, rc);
-			return rc;
-		}
-
-		rc = gpio_request(HAP_SHIFT_LVL_OE_GPIO, "hap_shft_lvl_oe");
-		if (rc) {
-			pr_err("%s: unable to request gpio %d (%d)\n",
-					__func__, HAP_SHIFT_LVL_OE_GPIO, rc);
-			return rc;
-		}
-
-		rc = gpio_direction_output(HAP_SHIFT_LVL_OE_GPIO, 0);
-		if (rc) {
-			pr_err("%s: Unable to set direction\n", __func__);
-			goto free_gpio;
-		}
-
-		xo_handle_d1 = msm_xo_get(MSM_XO_TCXO_D1, "isa1200");
-		if (IS_ERR(xo_handle_d1)) {
-			rc = PTR_ERR(xo_handle_d1);
-			pr_err("%s: failed to get the handle for D1(%d)\n",
-							__func__, rc);
-			goto gpio_set_dir;
-		}
-	} else {
-		gpio_free(HAP_SHIFT_LVL_OE_GPIO);
-
-		msm_xo_put(xo_handle_d1);
-	}
-
-	return 0;
-
-gpio_set_dir:
-	gpio_set_value(HAP_SHIFT_LVL_OE_GPIO, 0);
-free_gpio:
-	gpio_free(HAP_SHIFT_LVL_OE_GPIO);
-	return rc;
-}
-
-static struct isa1200_regulator isa1200_reg_data[] = {
-	{
-		.name = "vcc_i2c",
-		.min_uV = ISA_I2C_VTG_MIN_UV,
-		.max_uV = ISA_I2C_VTG_MAX_UV,
-		.load_uA = ISA_I2C_CURR_UA,
-	},
-};
-
-static struct isa1200_platform_data isa1200_1_pdata = {
-	.name = "vibrator",
-	.dev_setup = isa1200_dev_setup,
-	.power_on = isa1200_power,
-	.hap_en_gpio = PM_HAP_EN_GPIO,
-	.hap_len_gpio = PM_HAP_LEN_GPIO,
-	.max_timeout = 15000,
-	.mode_ctrl = PWM_GEN_MODE,
-	.pwm_fd = {
-		.pwm_div = 256,
-	},
-	.is_erm = false,
-	.smart_en = true,
-	.ext_clk_en = true,
-	.chip_en = 1,
-	.regulator_info = isa1200_reg_data,
-	.num_regulators = ARRAY_SIZE(isa1200_reg_data),
-};
-
-static struct i2c_board_info msm_isa1200_board_info[] __initdata = {
-	{
-		I2C_BOARD_INFO("isa1200_1", 0x90>>1),
-		.platform_data = &isa1200_1_pdata,
-	},
-};
-
-#define CYTTSP_TS_GPIO_IRQ		11
-#define CYTTSP_TS_SLEEP_GPIO		50
-#define CYTTSP_TS_RESOUT_N_GPIO		52
-
-/*virtual key support */
-static ssize_t tma340_vkeys_show(struct kobject *kobj,
-			struct kobj_attribute *attr, char *buf)
-{
-	return snprintf(buf, 200,
-	__stringify(EV_KEY) ":" __stringify(KEY_BACK) ":73:1120:97:97"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":230:1120:97:97"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":389:1120:97:97"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":544:1120:97:97"
-	"\n");
-}
-
-static struct kobj_attribute tma340_vkeys_attr = {
-	.attr = {
-		.mode = S_IRUGO,
-	},
-	.show = &tma340_vkeys_show,
-};
-
-static struct attribute *tma340_properties_attrs[] = {
-	&tma340_vkeys_attr.attr,
-	NULL
-};
-
-static struct attribute_group tma340_properties_attr_group = {
-	.attrs = tma340_properties_attrs,
-};
-
-
-static int cyttsp_platform_init(struct i2c_client *client)
-{
-	int rc = 0;
-	static struct kobject *tma340_properties_kobj;
-
-	tma340_vkeys_attr.attr.name = "virtualkeys.cyttsp-i2c";
-	tma340_properties_kobj = kobject_create_and_add("board_properties",
-								NULL);
-	if (tma340_properties_kobj)
-		rc = sysfs_create_group(tma340_properties_kobj,
-					&tma340_properties_attr_group);
-	if (!tma340_properties_kobj || rc)
-		pr_err("%s: failed to create board_properties\n",
-				__func__);
-
-	return 0;
-}
-
-static struct cyttsp_regulator regulator_data[] = {
-	{
-		.name = "vdd",
-		.min_uV = CY_TMA300_VTG_MIN_UV,
-		.max_uV = CY_TMA300_VTG_MAX_UV,
-		.hpm_load_uA = CY_TMA300_CURR_24HZ_UA,
-		.lpm_load_uA = CY_TMA300_SLEEP_CURR_UA,
-	},
-	/* TODO: Remove after runtime PM is enabled in I2C driver */
-	{
-		.name = "vcc_i2c",
-		.min_uV = CY_I2C_VTG_MIN_UV,
-		.max_uV = CY_I2C_VTG_MAX_UV,
-		.hpm_load_uA = CY_I2C_CURR_UA,
-		.lpm_load_uA = CY_I2C_SLEEP_CURR_UA,
-	},
-};
-
-static struct cyttsp_platform_data cyttsp_pdata = {
-	.panel_maxx = 634,
-	.panel_maxy = 1166,
-	.disp_maxx = 616,
-	.disp_maxy = 1023,
-	.disp_minx = 0,
-	.disp_miny = 16,
-	.flags = 0x01,
-	.gen = CY_GEN3,	/* or */
-	.use_st = CY_USE_ST,
-	.use_mt = CY_USE_MT,
-	.use_hndshk = CY_SEND_HNDSHK,
-	.use_trk_id = CY_USE_TRACKING_ID,
-	.use_sleep = CY_USE_DEEP_SLEEP_SEL | CY_USE_LOW_POWER_SEL,
-	.use_gestures = CY_USE_GESTURES,
-	.fw_fname = "cyttsp_8960_cdp.hex",
-	/* activate up to 4 groups
-	 * and set active distance
-	 */
-	.gest_set = CY_GEST_GRP1 | CY_GEST_GRP2 |
-				CY_GEST_GRP3 | CY_GEST_GRP4 |
-				CY_ACT_DIST,
-	/* change act_intrvl to customize the Active power state
-	 * scanning/processing refresh interval for Operating mode
-	 */
-	.act_intrvl = CY_ACT_INTRVL_DFLT,
-	/* change tch_tmout to customize the touch timeout for the
-	 * Active power state for Operating mode
-	 */
-	.tch_tmout = CY_TCH_TMOUT_DFLT,
-	/* change lp_intrvl to customize the Low Power power state
-	 * scanning/processing refresh interval for Operating mode
-	 */
-	.lp_intrvl = CY_LP_INTRVL_DFLT,
-	.sleep_gpio = CYTTSP_TS_SLEEP_GPIO,
-	.resout_gpio = CYTTSP_TS_RESOUT_N_GPIO,
-	.irq_gpio = CYTTSP_TS_GPIO_IRQ,
-	.regulator_info = regulator_data,
-	.num_regulators = ARRAY_SIZE(regulator_data),
-	.init = cyttsp_platform_init,
-	.correct_fw_ver = 9,
-};
-
-static struct i2c_board_info cyttsp_info[] __initdata = {
-	{
-		I2C_BOARD_INFO(CY_I2C_NAME, 0x24),
-		.platform_data = &cyttsp_pdata,
-#ifndef CY_USE_TIMER
-		.irq = MSM_GPIO_TO_INT(CYTTSP_TS_GPIO_IRQ),
-#endif /* CY_USE_TIMER */
-	},
-};
-
-/* configuration data */
-static const u8 mxt_config_data[] = {
-	/* T6 Object */
-	0, 0, 0, 0, 0, 0,
-	/* T38 Object */
-	11, 2, 0, 11, 11, 11, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0,
-	/* T7 Object */
-	100, 16, 50,
-	/* T8 Object */
-	8, 0, 0, 0, 0, 0, 8, 14, 50, 215,
-	/* T9 Object */
-	131, 0, 0, 26, 42, 0, 32, 63, 3, 5,
-	0, 2, 1, 113, 10, 10, 8, 10, 255, 2,
-	85, 5, 0, 0, 20, 20, 75, 25, 202, 29,
-	10, 10, 45, 46,
-	/* T15 Object */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0,
-	/* T22 Object */
-	5, 0, 0, 0, 0, 0, 0, 0, 30, 0,
-	0, 0, 5, 8, 10, 13, 0,
-	/* T24 Object */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* T25 Object */
-	3, 0, 188, 52, 52, 33, 0, 0, 0, 0,
-	0, 0, 0, 0,
-	/* T27 Object */
-	0, 0, 0, 0, 0, 0, 0,
-	/* T28 Object */
-	0, 0, 0, 8, 12, 60,
-	/* T40 Object */
-	0, 0, 0, 0, 0,
-	/* T41 Object */
-	0, 0, 0, 0, 0, 0,
-	/* T43 Object */
-	0, 0, 0, 0, 0, 0,
-};
-
-#define MXT_TS_GPIO_IRQ		11
-#define MXT_TS_LDO_EN_GPIO	50
-#define MXT_TS_RESET_GPIO	52
-
-static void mxt_init_hw_liquid(void)
-{
-	int rc;
-
-	rc = gpio_request(MXT_TS_GPIO_IRQ, "mxt_ts_irq_gpio");
-	if (rc) {
-		pr_err("%s: unable to request mxt_ts_irq gpio [%d]\n",
-				__func__, MXT_TS_GPIO_IRQ);
-		return;
-	}
-
-	rc = gpio_direction_input(MXT_TS_GPIO_IRQ);
-	if (rc) {
-		pr_err("%s: unable to set_direction for mxt_ts_irq gpio [%d]\n",
-				__func__, MXT_TS_GPIO_IRQ);
-		goto err_irq_gpio_req;
-	}
-
-	rc = gpio_request(MXT_TS_LDO_EN_GPIO, "mxt_ldo_en_gpio");
-	if (rc) {
-		pr_err("%s: unable to request mxt_ldo_en gpio [%d]\n",
-				__func__, MXT_TS_LDO_EN_GPIO);
-		goto err_irq_gpio_req;
-	}
-
-	rc = gpio_direction_output(MXT_TS_LDO_EN_GPIO, 1);
-	if (rc) {
-		pr_err("%s: unable to set_direction for mxt_ldo_en gpio [%d]\n",
-				__func__, MXT_TS_LDO_EN_GPIO);
-		goto err_ldo_gpio_req;
-	}
-
-	rc = gpio_request(MXT_TS_RESET_GPIO, "mxt_reset_gpio");
-	if (rc) {
-		pr_err("%s: unable to request mxt_reset gpio [%d]\n",
-				__func__, MXT_TS_RESET_GPIO);
-		goto err_ldo_gpio_set_dir;
-	}
-
-	rc = gpio_direction_output(MXT_TS_RESET_GPIO, 1);
-	if (rc) {
-		pr_err("%s: unable to set_direction for mxt_reset gpio [%d]\n",
-				__func__, MXT_TS_RESET_GPIO);
-		goto err_reset_gpio_req;
-	}
-
-	return;
-
-err_reset_gpio_req:
-	gpio_free(MXT_TS_RESET_GPIO);
-err_ldo_gpio_set_dir:
-	gpio_set_value(MXT_TS_LDO_EN_GPIO, 0);
-err_ldo_gpio_req:
-	gpio_free(MXT_TS_LDO_EN_GPIO);
-err_irq_gpio_req:
-	gpio_free(MXT_TS_GPIO_IRQ);
-}
-
-static struct mxt_platform_data mxt_platform_data = {
-	.config			= mxt_config_data,
-	.config_length		= ARRAY_SIZE(mxt_config_data),
-	.x_size			= 1365,
-	.y_size			= 767,
-	.irqflags		= IRQF_TRIGGER_FALLING,
-	.i2c_pull_up		= true,
-};
-
-static struct i2c_board_info mxt_device_info[] __initdata = {
-	{
-		I2C_BOARD_INFO("atmel_mxt_ts", 0x5b),
-		.platform_data = &mxt_platform_data,
-		.irq = MSM_GPIO_TO_INT(MXT_TS_GPIO_IRQ),
-	},
-};
-
-static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
-{
-}
-
-static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi4_pdata = {
-	.clk_freq = 100000,
-	.src_clk_rate = 24000000,
-	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
-};
-
-static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi3_pdata = {
-	.clk_freq = 100000,
-	.src_clk_rate = 24000000,
-	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
-};
-
-static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi10_pdata = {
-	.clk_freq = 100000,
-	.src_clk_rate = 24000000,
-	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
-};
-
-static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi12_pdata = {
-	.clk_freq = 100000,
-	.src_clk_rate = 24000000,
-	.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
-};
-
-static struct msm_rpm_platform_data msm_rpm_data = {
-	.reg_base_addrs = {
-		[MSM_RPM_PAGE_STATUS] = MSM_RPM_BASE,
-		[MSM_RPM_PAGE_CTRL] = MSM_RPM_BASE + 0x400,
-		[MSM_RPM_PAGE_REQ] = MSM_RPM_BASE + 0x600,
-		[MSM_RPM_PAGE_ACK] = MSM_RPM_BASE + 0xa00,
-	},
-
-	.irq_ack = RPM_APCC_CPU0_GP_HIGH_IRQ,
-	.irq_err = RPM_APCC_CPU0_GP_LOW_IRQ,
-	.irq_vmpm = RPM_APCC_CPU0_GP_MEDIUM_IRQ,
-	.msm_apps_ipc_rpm_reg = MSM_APCS_GCC_BASE + 0x008,
-	.msm_apps_ipc_rpm_val = 4,
-};
-
-static struct ks8851_pdata spi_eth_pdata = {
-	.irq_gpio = KS8851_IRQ_GPIO,
-	.rst_gpio = KS8851_RST_GPIO,
-};
-
-static struct spi_board_info spi_board_info[] __initdata = {
-	{
-		.modalias               = "ks8851",
-		.irq                    = MSM_GPIO_TO_INT(KS8851_IRQ_GPIO),
-		.max_speed_hz           = 19200000,
-		.bus_num                = 0,
-		.chip_select            = 0,
-		.mode                   = SPI_MODE_0,
-		.platform_data		= &spi_eth_pdata
-	},
-	{
-		.modalias               = "dsi_novatek_3d_panel_spi",
-		.max_speed_hz           = 10800000,
-		.bus_num                = 0,
-		.chip_select            = 1,
-		.mode                   = SPI_MODE_0,
-	},
-};
-
-static struct platform_device msm_device_saw_core0 = {
-	.name          = "saw-regulator",
-	.id            = 0,
-	.dev	= {
-		.platform_data = &msm_saw_regulator_pdata_s5,
-	},
-};
-
-static struct platform_device msm_device_saw_core1 = {
-	.name          = "saw-regulator",
-	.id            = 1,
-	.dev	= {
-		.platform_data = &msm_saw_regulator_pdata_s6,
-	},
-};
-
-#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
-static struct platform_device wfd_device = {
-	.name          = "msm_wfd",
-	.id            = -1,
-};
-#endif
-
-static struct tsens_platform_data msm_tsens_pdata  = {
-		.slope			= 910,
-		.tsens_factor		= 1000,
-		.hw_type		= MSM_8960,
-		.tsens_num_sensor	= 5,
-};
-
-static struct platform_device msm_tsens_device = {
-	.name	= "tsens8960-tm",
-	.id	= -1,
-	.dev	= {
-		.platform_data = &msm_tsens_pdata,
-	},
-};
-
-#ifdef CONFIG_MSM_FAKE_BATTERY
-static struct platform_device fish_battery_device = {
-	.name = "fish_battery",
-};
-#endif
-
-static struct platform_device msm8960_device_ext_5v_vreg __devinitdata = {
-	.name	= GPIO_REGULATOR_DEV_NAME,
-	.id	= PM8921_MPP_PM_TO_SYS(7),
-	.dev	= {
-		.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
-	},
-};
-
-static struct platform_device msm8960_device_ext_l2_vreg __devinitdata = {
-	.name	= GPIO_REGULATOR_DEV_NAME,
-	.id	= 91,
-	.dev	= {
-		.platform_data = &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_L2],
-	},
-};
-
-static struct platform_device msm8960_device_ext_3p3v_vreg __devinitdata = {
-	.name	= GPIO_REGULATOR_DEV_NAME,
-	.id	= PM8921_GPIO_PM_TO_SYS(17),
-	.dev	= {
-		.platform_data =
-			&msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_3P3V],
-	},
-};
-
-static struct platform_device msm8960_device_rpm_regulator __devinitdata = {
-	.name	= "rpm-regulator",
-	.id	= -1,
-	.dev	= {
-		.platform_data = &msm_rpm_regulator_pdata,
-	},
-};
-
-static struct msm_rpm_log_platform_data msm_rpm_log_pdata = {
-	.phys_addr_base = 0x0010C000,
-	.reg_offsets = {
-		[MSM_RPM_LOG_PAGE_INDICES] = 0x00000080,
-		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
-	},
-	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
-};
-
-static struct platform_device msm_rpm_log_device = {
-	.name	= "msm_rpm_log",
-	.id	= -1,
-	.dev	= {
-		.platform_data = &msm_rpm_log_pdata,
-	},
-};
-
-static struct platform_device *common_devices[] __initdata = {
-	&msm8960_device_dmov,
-	&msm_device_smd,
-	&msm8960_device_uart_gsbi5,
-	&msm_device_uart_dm6,
-	&msm_device_saw_core0,
-	&msm_device_saw_core1,
-	&msm8960_device_ext_5v_vreg,
-	&msm8960_device_ext_l2_vreg,
-	&msm8960_device_ssbi_pm8921,
-	&msm8960_device_qup_spi_gsbi1,
-	&msm8960_device_qup_i2c_gsbi3,
-	&msm8960_device_qup_i2c_gsbi4,
-	&msm8960_device_qup_i2c_gsbi10,
-#ifndef CONFIG_MSM_DSPS
-	&msm8960_device_qup_i2c_gsbi12,
-#endif
-	&msm_slim_ctrl,
-	&msm_device_wcnss_wlan,
-#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
-		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
-	&qcrypto_device,
-#endif
-
-#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
-		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
-	&qcedev_device,
-#endif
-#ifdef CONFIG_MSM_ROTATOR
-	&msm_rotator_device,
-#endif
-	&msm_device_sps,
-#ifdef CONFIG_MSM_FAKE_BATTERY
-	&fish_battery_device,
-#endif
-#ifdef CONFIG_ANDROID_PMEM
-#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
-	&android_pmem_device,
-	&android_pmem_adsp_device,
-#endif
-	&android_pmem_audio_device,
-#endif
-	&msm_fb_device,
-	&msm_device_vidc,
-	&msm_device_bam_dmux,
-	&msm_fm_platform_init,
-
-#ifdef CONFIG_HW_RANDOM_MSM
-	&msm_device_rng,
-#endif
-	&msm_rpm_device,
-#ifdef CONFIG_ION_MSM
-	&ion_dev,
-#endif
-	&msm_rpm_log_device,
-	&msm_rpm_stat_device,
-	&msm_device_tz_log,
-
-#ifdef CONFIG_MSM_QDSS
-	&msm_etb_device,
-	&msm_tpiu_device,
-	&msm_funnel_device,
-	&msm_debug_device,
-	&msm_ptm_device,
-#endif
-	&msm_device_dspcrashd_8960,
-	&msm8960_device_watchdog,
-#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
-	&wfd_panel_device,
-	&wfd_device,
-#endif
-};
-
-static struct platform_device *sim_devices[] __initdata = {
-	&msm8960_device_otg,
-	&msm8960_device_gadget_peripheral,
-	&msm_device_hsusb_host,
-	&msm_device_hsic_host,
-	&android_usb_device,
-	&msm_device_vidc,
-	&mipi_dsi_simulator_panel_device,
-	&msm_bus_apps_fabric,
-	&msm_bus_sys_fabric,
-	&msm_bus_mm_fabric,
-	&msm_bus_sys_fpb,
-	&msm_bus_cpss_fpb,
-	&msm_pcm,
-	&msm_pcm_routing,
-	&msm_cpudai0,
-	&msm_cpudai1,
-	&msm_cpudai_hdmi_rx,
-	&msm_cpudai_bt_rx,
-	&msm_cpudai_bt_tx,
-	&msm_cpudai_fm_rx,
-	&msm_cpudai_fm_tx,
-	&msm_cpudai_auxpcm_rx,
-	&msm_cpudai_auxpcm_tx,
-	&msm_cpu_fe,
-	&msm_stub_codec,
-	&msm_voice,
-	&msm_voip,
-	&msm_lpa_pcm,
-
-#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
-		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
-	&qcrypto_device,
-#endif
-
-#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
-		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
-	&qcedev_device,
-#endif
-};
-
-static struct platform_device *rumi3_devices[] __initdata = {
-	&msm_kgsl_3d0,
-	&msm_kgsl_2d0,
-	&msm_kgsl_2d1,
-	&mipi_dsi_renesas_panel_device,
-#ifdef CONFIG_MSM_GEMINI
-	&msm8960_gemini_device,
-#endif
-};
-
-static struct platform_device *cdp_devices[] __initdata = {
-	&msm8960_device_otg,
-	&msm8960_device_gadget_peripheral,
-	&msm_device_hsusb_host,
-	&android_usb_device,
-	&msm_pcm,
-	&msm_pcm_routing,
-	&msm_cpudai0,
-	&msm_cpudai1,
-	&msm_cpudai_hdmi_rx,
-	&msm_cpudai_bt_rx,
-	&msm_cpudai_bt_tx,
-	&msm_cpudai_fm_rx,
-	&msm_cpudai_fm_tx,
-	&msm_cpudai_auxpcm_rx,
-	&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
-	&mipi_dsi_novatek_panel_device,
-#ifdef CONFIG_MSM_GEMINI
-	&msm8960_gemini_device,
-#endif
-	&msm_voice,
-	&msm_voip,
-	&msm_lpa_pcm,
-	&msm_cpudai_afe_01_rx,
-	&msm_cpudai_afe_01_tx,
-	&msm_cpudai_afe_02_rx,
-	&msm_cpudai_afe_02_tx,
-	&msm_pcm_afe,
-#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-	&hdmi_msm_device,
-#endif
-	&msm_pcm_hostless,
-	&msm_bus_apps_fabric,
-	&msm_bus_sys_fabric,
-	&msm_bus_mm_fabric,
-	&msm_bus_sys_fpb,
-	&msm_bus_cpss_fpb,
-	&msm_tsens_device,
-};
-
-static void __init msm8960_i2c_init(void)
-{
-	msm8960_device_qup_i2c_gsbi4.dev.platform_data =
-					&msm8960_i2c_qup_gsbi4_pdata;
-
-	msm8960_device_qup_i2c_gsbi3.dev.platform_data =
-					&msm8960_i2c_qup_gsbi3_pdata;
-
-	msm8960_device_qup_i2c_gsbi10.dev.platform_data =
-					&msm8960_i2c_qup_gsbi10_pdata;
-
-	msm8960_device_qup_i2c_gsbi12.dev.platform_data =
-					&msm8960_i2c_qup_gsbi12_pdata;
-}
-
-static void __init msm8960_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 pm8xxx_irq_platform_data pm8xxx_irq_pdata __devinitdata = {
-	.irq_base		= PM8921_IRQ_BASE,
-	.devirq			= MSM_GPIO_TO_INT(104),
-	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
-};
-
-static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata __devinitdata = {
-	.gpio_base	= PM8921_GPIO_PM_TO_SYS(1),
-};
-
-static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata __devinitdata = {
-	.mpp_base	= PM8921_MPP_PM_TO_SYS(1),
-};
-
-static struct pm8xxx_rtc_platform_data pm8xxx_rtc_pdata __devinitdata = {
-	.rtc_write_enable       = false,
-	.rtc_alarm_powerup	= false,
-};
-
-static struct pm8xxx_pwrkey_platform_data pm8xxx_pwrkey_pdata = {
-	.pull_up		= 1,
-	.kpd_trigger_delay_us	= 970,
-	.wakeup			= 1,
-};
-
-/* Rotate lock key is not available so use F1 */
-#define KEY_ROTATE_LOCK KEY_F1
-
-static const unsigned int keymap_liquid[] = {
-	KEY(0, 0, KEY_VOLUMEUP),
-	KEY(0, 1, KEY_VOLUMEDOWN),
-	KEY(1, 3, KEY_ROTATE_LOCK),
-	KEY(1, 4, KEY_HOME),
-};
-
-static struct matrix_keymap_data keymap_data_liquid = {
-	.keymap_size    = ARRAY_SIZE(keymap_liquid),
-	.keymap         = keymap_liquid,
-};
-
-static struct pm8xxx_keypad_platform_data keypad_data_liquid = {
-	.input_name             = "keypad_8960_liquid",
-	.input_phys_device      = "keypad_8960/input0",
-	.num_rows               = 2,
-	.num_cols               = 5,
-	.rows_gpio_start	= PM8921_GPIO_PM_TO_SYS(9),
-	.cols_gpio_start	= PM8921_GPIO_PM_TO_SYS(1),
-	.debounce_ms            = 15,
-	.scan_delay_ms          = 32,
-	.row_hold_ns            = 91500,
-	.wakeup                 = 1,
-	.keymap_data            = &keymap_data_liquid,
-};
-
-
-static const unsigned int keymap[] = {
-	KEY(0, 0, KEY_VOLUMEUP),
-	KEY(0, 1, KEY_VOLUMEDOWN),
-	KEY(0, 2, KEY_CAMERA_SNAPSHOT),
-	KEY(0, 3, KEY_CAMERA_FOCUS),
-};
-
-static struct matrix_keymap_data keymap_data = {
-	.keymap_size    = ARRAY_SIZE(keymap),
-	.keymap         = keymap,
-};
-
-static struct pm8xxx_keypad_platform_data keypad_data = {
-	.input_name             = "keypad_8960",
-	.input_phys_device      = "keypad_8960/input0",
-	.num_rows               = 1,
-	.num_cols               = 5,
-	.rows_gpio_start	= PM8921_GPIO_PM_TO_SYS(9),
-	.cols_gpio_start	= PM8921_GPIO_PM_TO_SYS(1),
-	.debounce_ms            = 15,
-	.scan_delay_ms          = 32,
-	.row_hold_ns            = 91500,
-	.wakeup                 = 1,
-	.keymap_data            = &keymap_data,
-};
-
-static const unsigned int keymap_sim[] = {
-	KEY(0, 0, KEY_7),
-	KEY(0, 1, KEY_DOWN),
-	KEY(0, 2, KEY_UP),
-	KEY(0, 3, KEY_RIGHT),
-	KEY(0, 4, KEY_ENTER),
-	KEY(0, 5, KEY_L),
-	KEY(0, 6, KEY_BACK),
-	KEY(0, 7, KEY_M),
-
-	KEY(1, 0, KEY_LEFT),
-	KEY(1, 1, KEY_SEND),
-	KEY(1, 2, KEY_1),
-	KEY(1, 3, KEY_4),
-	KEY(1, 4, KEY_CLEAR),
-	KEY(1, 5, KEY_MSDOS),
-	KEY(1, 6, KEY_SPACE),
-	KEY(1, 7, KEY_COMMA),
-
-	KEY(2, 0, KEY_6),
-	KEY(2, 1, KEY_5),
-	KEY(2, 2, KEY_8),
-	KEY(2, 3, KEY_3),
-	KEY(2, 4, KEY_NUMERIC_STAR),
-	KEY(2, 5, KEY_UP),
-	KEY(2, 6, KEY_DOWN),
-	KEY(2, 7, KEY_LEFTSHIFT),
-
-	KEY(3, 0, KEY_9),
-	KEY(3, 1, KEY_NUMERIC_POUND),
-	KEY(3, 2, KEY_0),
-	KEY(3, 3, KEY_2),
-	KEY(3, 4, KEY_SLEEP),
-	KEY(3, 5, KEY_F1),
-	KEY(3, 6, KEY_F2),
-	KEY(3, 7, KEY_F3),
-
-	KEY(4, 0, KEY_BACK),
-	KEY(4, 1, KEY_HOME),
-	KEY(4, 2, KEY_MENU),
-	KEY(4, 3, KEY_VOLUMEUP),
-	KEY(4, 4, KEY_VOLUMEDOWN),
-	KEY(4, 5, KEY_F4),
-	KEY(4, 6, KEY_F5),
-	KEY(4, 7, KEY_F6),
-
-	KEY(5, 0, KEY_R),
-	KEY(5, 1, KEY_T),
-	KEY(5, 2, KEY_Y),
-	KEY(5, 3, KEY_LEFTALT),
-	KEY(5, 4, KEY_KPENTER),
-	KEY(5, 5, KEY_Q),
-	KEY(5, 6, KEY_W),
-	KEY(5, 7, KEY_E),
-
-	KEY(6, 0, KEY_F),
-	KEY(6, 1, KEY_G),
-	KEY(6, 2, KEY_H),
-	KEY(6, 3, KEY_CAPSLOCK),
-	KEY(6, 4, KEY_PAGEUP),
-	KEY(6, 5, KEY_A),
-	KEY(6, 6, KEY_S),
-	KEY(6, 7, KEY_D),
-
-	KEY(7, 0, KEY_V),
-	KEY(7, 1, KEY_B),
-	KEY(7, 2, KEY_N),
-	KEY(7, 3, KEY_MENU),
-	KEY(7, 4, KEY_PAGEDOWN),
-	KEY(7, 5, KEY_Z),
-	KEY(7, 6, KEY_X),
-	KEY(7, 7, KEY_C),
-
-	KEY(8, 0, KEY_P),
-	KEY(8, 1, KEY_J),
-	KEY(8, 2, KEY_K),
-	KEY(8, 3, KEY_INSERT),
-	KEY(8, 4, KEY_LINEFEED),
-	KEY(8, 5, KEY_U),
-	KEY(8, 6, KEY_I),
-	KEY(8, 7, KEY_O),
-
-	KEY(9, 0, KEY_4),
-	KEY(9, 1, KEY_5),
-	KEY(9, 2, KEY_6),
-	KEY(9, 3, KEY_7),
-	KEY(9, 4, KEY_8),
-	KEY(9, 5, KEY_1),
-	KEY(9, 6, KEY_2),
-	KEY(9, 7, KEY_3),
-
-	KEY(10, 0, KEY_F7),
-	KEY(10, 1, KEY_F8),
-	KEY(10, 2, KEY_F9),
-	KEY(10, 3, KEY_F10),
-	KEY(10, 4, KEY_FN),
-	KEY(10, 5, KEY_9),
-	KEY(10, 6, KEY_0),
-	KEY(10, 7, KEY_DOT),
-
-	KEY(11, 0, KEY_LEFTCTRL),
-	KEY(11, 1, KEY_F11),
-	KEY(11, 2, KEY_ENTER),
-	KEY(11, 3, KEY_SEARCH),
-	KEY(11, 4, KEY_DELETE),
-	KEY(11, 5, KEY_RIGHT),
-	KEY(11, 6, KEY_LEFT),
-	KEY(11, 7, KEY_RIGHTSHIFT),
-	KEY(0, 0, KEY_VOLUMEUP),
-	KEY(0, 1, KEY_VOLUMEDOWN),
-	KEY(0, 2, KEY_CAMERA_SNAPSHOT),
-	KEY(0, 3, KEY_CAMERA_FOCUS),
-};
-
-static struct matrix_keymap_data keymap_data_sim = {
-	.keymap_size    = ARRAY_SIZE(keymap_sim),
-	.keymap         = keymap_sim,
-};
-
-static struct pm8xxx_keypad_platform_data keypad_data_sim = {
-	.input_name             = "keypad_8960",
-	.input_phys_device      = "keypad_8960/input0",
-	.num_rows               = 12,
-	.num_cols               = 8,
-	.rows_gpio_start	= PM8921_GPIO_PM_TO_SYS(9),
-	.cols_gpio_start	= PM8921_GPIO_PM_TO_SYS(1),
-	.debounce_ms            = 15,
-	.scan_delay_ms          = 32,
-	.row_hold_ns            = 91500,
-	.wakeup                 = 1,
-	.keymap_data            = &keymap_data_sim,
-};
-
-static int pm8921_therm_mitigation[] = {
-	1100,
-	700,
-	600,
-	325,
-};
-
-static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
-	.safety_time		= 180,
-	.update_time		= 60000,
-	.max_voltage		= 4200,
-	.min_voltage		= 3200,
-	.resume_voltage_delta	= 100,
-	.term_current		= 100,
-	.cool_temp		= 10,
-	.warm_temp		= 40,
-	.temp_check_period	= 1,
-	.max_bat_chg_current	= 1100,
-	.cool_bat_chg_current	= 350,
-	.warm_bat_chg_current	= 350,
-	.cool_bat_voltage	= 4100,
-	.warm_bat_voltage	= 4100,
-	.thermal_mitigation	= pm8921_therm_mitigation,
-	.thermal_levels		= ARRAY_SIZE(pm8921_therm_mitigation),
-};
-
-static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
-	.priority		= 0,
-};
-
-static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
-	.r_sense		= 10,
-	.i_test			= 2500,
-	.v_failure		= 3000,
-	.calib_delay_ms		= 600000,
-};
-
-#define	PM8921_LC_LED_MAX_CURRENT	4	/* I = 4mA */
-#define PM8XXX_LED_PWM_PERIOD		1000
-#define PM8XXX_LED_PWM_DUTY_MS		20
-/**
- * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
- * driven using PWM feature.
- */
-#define PM8XXX_PWM_CHANNEL_NONE		-1
-
-static struct led_info pm8921_led_info[] = {
-	[0] = {
-		.name			= "led:battery_charging",
-		.default_trigger	= "battery-charging",
-	},
-	[1] = {
-		.name			= "led:battery_full",
-		.default_trigger	= "battery-full",
-	},
-};
-
-static struct led_platform_data pm8921_led_core_pdata = {
-	.num_leds = ARRAY_SIZE(pm8921_led_info),
-	.leds = pm8921_led_info,
-};
-
-static int pm8921_led0_pwm_duty_pcts[56] = {
-		1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
-		40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
-		80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
-		92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
-		58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
-		14, 10, 6, 4, 1
-};
-
-static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
-	.duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
-	.num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
-	.duty_ms = PM8XXX_LED_PWM_DUTY_MS,
-	.start_idx = 0,
-};
-
-static struct pm8xxx_led_config pm8921_led_configs[] = {
-	[0] = {
-		.id = PM8XXX_ID_LED_0,
-		.mode = PM8XXX_LED_MODE_PWM2,
-		.max_current = PM8921_LC_LED_MAX_CURRENT,
-		.pwm_channel = 5,
-		.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
-		.pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
-	},
-	[1] = {
-		.id = PM8XXX_ID_LED_1,
-		.mode = PM8XXX_LED_MODE_PWM1,
-		.max_current = PM8921_LC_LED_MAX_CURRENT,
-		.pwm_channel = 4,
-		.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
-	},
-};
-
-static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
-		.led_core = &pm8921_led_core_pdata,
-		.configs = pm8921_led_configs,
-		.num_configs = ARRAY_SIZE(pm8921_led_configs),
-};
-
-static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
-	.r_sense		= 10,
-};
-
-static struct pm8921_platform_data pm8921_platform_data __devinitdata = {
-	.irq_pdata		= &pm8xxx_irq_pdata,
-	.gpio_pdata		= &pm8xxx_gpio_pdata,
-	.mpp_pdata		= &pm8xxx_mpp_pdata,
-	.rtc_pdata              = &pm8xxx_rtc_pdata,
-	.pwrkey_pdata		= &pm8xxx_pwrkey_pdata,
-	.keypad_pdata		= &keypad_data,
-	.misc_pdata		= &pm8xxx_misc_pdata,
-	.regulator_pdatas	= msm_pm8921_regulator_pdata,
-	.charger_pdata		= &pm8921_chg_pdata,
-	.bms_pdata		= &pm8921_bms_pdata,
-	.adc_pdata		= &pm8xxx_adc_pdata,
-	.leds_pdata		= &pm8xxx_leds_pdata,
-	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
-};
-
-static struct msm_ssbi_platform_data msm8960_ssbi_pm8921_pdata __devinitdata = {
-	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
-	.slave	= {
-		.name			= "pm8921-core",
-		.platform_data		= &pm8921_platform_data,
-	},
-};
-
-static struct msm_cpuidle_state msm_cstates[] __initdata = {
-	{0, 0, "C0", "WFI",
-		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
-
-	{0, 1, "C1", "STANDALONE_POWER_COLLAPSE",
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
-
-	{0, 2, "C2", "POWER_COLLAPSE",
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE},
-
-	{1, 0, "C0", "WFI",
-		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
-
-	{1, 1, "C1", "STANDALONE_POWER_COLLAPSE",
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
-};
-
-static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR * 2] = {
-	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
-		.idle_supported = 1,
-		.suspend_supported = 1,
-		.idle_enabled = 0,
-		.suspend_enabled = 0,
-	},
-
-	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
-		.idle_supported = 1,
-		.suspend_supported = 1,
-		.idle_enabled = 0,
-		.suspend_enabled = 0,
-	},
-
-	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
-		.idle_supported = 1,
-		.suspend_supported = 1,
-		.idle_enabled = 1,
-		.suspend_enabled = 1,
-	},
-
-	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
-		.idle_supported = 0,
-		.suspend_supported = 1,
-		.idle_enabled = 0,
-		.suspend_enabled = 0,
-	},
-
-	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
-		.idle_supported = 1,
-		.suspend_supported = 1,
-		.idle_enabled = 0,
-		.suspend_enabled = 0,
-	},
-
-	[MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
-		.idle_supported = 1,
-		.suspend_supported = 0,
-		.idle_enabled = 1,
-		.suspend_enabled = 0,
-	},
-};
-
-static struct msm_rpmrs_level msm_rpmrs_levels[] __initdata = {
-	{
-		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT,
-		MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
-		true,
-		100, 8000, 100000, 1,
-	},
-
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
-		MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
-		true,
-		2000, 6000, 60100000, 3000,
-	},
-
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
-		MSM_RPMRS_LIMITS(ON, GDHS, MAX, ACTIVE),
-		false,
-		4200, 5000, 60350000, 3500,
-	},
-
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
-		MSM_RPMRS_LIMITS(ON, HSFS_OPEN, MAX, ACTIVE),
-		false,
-		6300, 4500, 65350000, 4800,
-	},
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
-		MSM_RPMRS_LIMITS(ON, HSFS_OPEN, ACTIVE, RET_HIGH),
-		false,
-		7000, 3500, 66600000, 5150,
-	},
-
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
-		MSM_RPMRS_LIMITS(OFF, GDHS, MAX, ACTIVE),
-		false,
-		11700, 2500, 67850000, 5500,
-	},
-
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
-		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, MAX, ACTIVE),
-		false,
-		13800, 2000, 71850000, 6800,
-	},
-
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
-		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, ACTIVE, RET_HIGH),
-		false,
-		29700, 500, 75850000, 8800,
-	},
-
-	{
-		MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
-		MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, RET_HIGH, RET_LOW),
-		false,
-		29700, 0, 76350000, 9800,
-	},
-};
-
-#ifdef CONFIG_I2C
-#define I2C_SURF 1
-#define I2C_FFA  (1 << 1)
-#define I2C_RUMI (1 << 2)
-#define I2C_SIM  (1 << 3)
-#define I2C_FLUID (1 << 4)
-#define I2C_LIQUID (1 << 5)
-
-struct i2c_registry {
-	u8                     machs;
-	int                    bus;
-	struct i2c_board_info *info;
-	int                    len;
-};
-
-#ifdef CONFIG_MSM_CAMERA
-static struct i2c_board_info msm_camera_boardinfo[] __initdata = {
-#ifdef CONFIG_IMX074
-	{
-	I2C_BOARD_INFO("imx074", 0x1A),
-	},
-#endif
-#ifdef CONFIG_OV2720
-	{
-	I2C_BOARD_INFO("ov2720", 0x6C),
-	},
-#endif
-#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
-	{
-	I2C_BOARD_INFO("sc628a", 0x6E),
-	},
-#endif
-};
-#endif
-
-/* Sensors DSPS platform data */
-#ifdef CONFIG_MSM_DSPS
-#define DSPS_PIL_GENERIC_NAME		"dsps"
-#endif /* CONFIG_MSM_DSPS */
-
-static void __init msm8960_init_dsps(void)
-{
-#ifdef CONFIG_MSM_DSPS
-	struct msm_dsps_platform_data *pdata =
-		msm_dsps_device.dev.platform_data;
-	pdata->pil_name = DSPS_PIL_GENERIC_NAME;
-	pdata->gpios = NULL;
-	pdata->gpios_num = 0;
-
-	platform_device_register(&msm_dsps_device);
-#endif /* CONFIG_MSM_DSPS */
-}
-
-static void __init msm8960_init_hsic(void)
-{
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-	uint32_t version = socinfo_get_version();
-
-	pr_info("%s: version:%d mtp:%d\n", __func__,
-			SOCINFO_VERSION_MAJOR(version),
-			machine_is_msm8960_mtp());
-
-	if ((SOCINFO_VERSION_MAJOR(version) == 1) ||
-			machine_is_msm8960_mtp() ||
-			machine_is_msm8960_fluid())
-		return;
-
-	msm_gpiomux_install(msm8960_hsic_configs,
-			ARRAY_SIZE(msm8960_hsic_configs));
-
-	platform_device_register(&msm_device_hsic_host);
-#endif
-}
-
-
-#ifdef CONFIG_ISL9519_CHARGER
-static struct isl_platform_data isl_data __initdata = {
-	.valid_n_gpio		= 0,	/* Not required when notify-by-pmic */
-	.chg_detection_config	= NULL,	/* Not required when notify-by-pmic */
-	.max_system_voltage	= 4200,
-	.min_system_voltage	= 3200,
-	.chgcurrent		= 1000, /* 1900, */
-	.term_current		= 400,	/* Need fine tuning */
-	.input_current		= 2048,
-};
-
-static struct i2c_board_info isl_charger_i2c_info[] __initdata = {
-	{
-		I2C_BOARD_INFO("isl9519q", 0x9),
-		.irq		= 0,	/* Not required when notify-by-pmic */
-		.platform_data	= &isl_data,
-	},
-};
-#endif /* CONFIG_ISL9519_CHARGER */
-
-static struct i2c_registry msm8960_i2c_devices[] __initdata = {
-#ifdef CONFIG_MSM_CAMERA
-	{
-		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI,
-		MSM_8960_GSBI4_QUP_I2C_BUS_ID,
-		msm_camera_boardinfo,
-		ARRAY_SIZE(msm_camera_boardinfo),
-	},
-#endif
-#ifdef CONFIG_ISL9519_CHARGER
-	{
-		I2C_LIQUID,
-		MSM_8960_GSBI10_QUP_I2C_BUS_ID,
-		isl_charger_i2c_info,
-		ARRAY_SIZE(isl_charger_i2c_info),
-	},
-#endif /* CONFIG_ISL9519_CHARGER */
-	{
-		I2C_SURF | I2C_FFA | I2C_FLUID,
-		MSM_8960_GSBI3_QUP_I2C_BUS_ID,
-		cyttsp_info,
-		ARRAY_SIZE(cyttsp_info),
-	},
-	{
-		I2C_LIQUID,
-		MSM_8960_GSBI3_QUP_I2C_BUS_ID,
-		mxt_device_info,
-		ARRAY_SIZE(mxt_device_info),
-	},
-	{
-		I2C_LIQUID,
-		MSM_8960_GSBI10_QUP_I2C_BUS_ID,
-		msm_isa1200_board_info,
-		ARRAY_SIZE(msm_isa1200_board_info),
-	},
-};
-#endif /* CONFIG_I2C */
-
-static void __init register_i2c_devices(void)
-{
-#ifdef CONFIG_I2C
-	u8 mach_mask = 0;
-	int i;
-
-	/* Build the matching 'supported_machs' bitmask */
-	if (machine_is_msm8960_cdp())
-		mach_mask = I2C_SURF;
-	else if (machine_is_msm8960_rumi3())
-		mach_mask = I2C_RUMI;
-	else if (machine_is_msm8960_sim())
-		mach_mask = I2C_SIM;
-	else if (machine_is_msm8960_fluid())
-		mach_mask = I2C_FLUID;
-	else if (machine_is_msm8960_liquid())
-		mach_mask = I2C_LIQUID;
-	else if (machine_is_msm8960_mtp())
-		mach_mask = I2C_FFA;
-	else
-		pr_err("unmatched machine ID in register_i2c_devices\n");
-
-	/* Run the array and install devices as appropriate */
-	for (i = 0; i < ARRAY_SIZE(msm8960_i2c_devices); ++i) {
-		if (msm8960_i2c_devices[i].machs & mach_mask)
-			i2c_register_board_info(msm8960_i2c_devices[i].bus,
-						msm8960_i2c_devices[i].info,
-						msm8960_i2c_devices[i].len);
-	}
-#endif
-}
-
-static void __init msm8960_sim_init(void)
-{
-	struct msm_watchdog_pdata *wdog_pdata = (struct msm_watchdog_pdata *)
-		&msm8960_device_watchdog.dev.platform_data;
-
-	wdog_pdata->bark_time = 15000;
-	BUG_ON(msm_rpm_init(&msm_rpm_data));
-	BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
-				ARRAY_SIZE(msm_rpmrs_levels)));
-	regulator_suppress_info_printing();
-	platform_device_register(&msm8960_device_rpm_regulator);
-	msm_clock_init(&msm8960_clock_init_data);
-	msm8960_device_ssbi_pm8921.dev.platform_data =
-				&msm8960_ssbi_pm8921_pdata;
-	pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
-
-	/* Simulator supports a QWERTY keypad */
-	pm8921_platform_data.keypad_pdata = &keypad_data_sim;
-
-	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
-	gpiomux_init();
-	msm8960_i2c_init();
-	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
-	msm_spm_l2_init(msm_spm_l2_data);
-	msm8960_init_buses();
-	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
-	pm8921_gpio_mpp_init();
-	platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices));
-	acpuclk_init(&acpuclk_8960_soc_data);
-
-	msm8960_device_qup_spi_gsbi1.dev.platform_data =
-				&msm8960_qup_spi_gsbi1_pdata;
-	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
-
-	msm8960_init_mmc();
-	msm_fb_add_devices();
-	slim_register_board_info(msm_slim_devices,
-		ARRAY_SIZE(msm_slim_devices));
-	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
-	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
-	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
-				msm_pm_data);
-	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
-}
-
-static void __init msm8960_rumi3_init(void)
-{
-	BUG_ON(msm_rpm_init(&msm_rpm_data));
-	BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
-				ARRAY_SIZE(msm_rpmrs_levels)));
-	regulator_suppress_info_printing();
-	platform_device_register(&msm8960_device_rpm_regulator);
-	msm_clock_init(&msm8960_dummy_clock_init_data);
-	gpiomux_init();
-	msm8960_device_ssbi_pm8921.dev.platform_data =
-				&msm8960_ssbi_pm8921_pdata;
-	pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
-	msm8960_device_qup_spi_gsbi1.dev.platform_data =
-				&msm8960_qup_spi_gsbi1_pdata;
-	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
-	msm8960_i2c_init();
-	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
-	msm_spm_l2_init(msm_spm_l2_data);
-	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
-	pm8921_gpio_mpp_init();
-	platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
-	msm8960_init_mmc();
-	register_i2c_devices();
-	msm_fb_add_devices();
-	slim_register_board_info(msm_slim_devices,
-		ARRAY_SIZE(msm_slim_devices));
-	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
-	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
-	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
-				msm_pm_data);
-	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
-}
-
-static void __init msm8960_cdp_init(void)
-{
-	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
-		pr_err("meminfo_init() failed!\n");
-
-	BUG_ON(msm_rpm_init(&msm_rpm_data));
-	BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
-				ARRAY_SIZE(msm_rpmrs_levels)));
-
-	pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
-	regulator_suppress_info_printing();
-	if (msm_xo_init())
-		pr_err("Failed to initialize XO votes\n");
-	platform_device_register(&msm8960_device_rpm_regulator);
-	msm_clock_init(&msm8960_clock_init_data);
-	if (machine_is_msm8960_liquid())
-		msm_otg_pdata.mhl_enable = true;
-	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
-	if (machine_is_msm8960_liquid()) {
-		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
-			msm_hsic_pdata.hub_reset = HSIC_HUB_RESET_GPIO;
-	}
-#endif
-	msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
-	gpiomux_init();
-	if (machine_is_msm8960_liquid())
-		pm8921_platform_data.keypad_pdata = &keypad_data_liquid;
-	msm8960_device_qup_spi_gsbi1.dev.platform_data =
-				&msm8960_qup_spi_gsbi1_pdata;
-	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
-	msm8960_device_ssbi_pm8921.dev.platform_data =
-				&msm8960_ssbi_pm8921_pdata;
-	pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
-	msm8960_i2c_init();
-	msm8960_gfx_init();
-	msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
-	msm_spm_l2_init(msm_spm_l2_data);
-	msm8960_init_buses();
-	platform_add_devices(msm_footswitch_devices,
-		msm_num_footswitch_devices);
-	if (machine_is_msm8960_liquid())
-		platform_device_register(&msm8960_device_ext_3p3v_vreg);
-	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
-	pm8921_gpio_mpp_init();
-	platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
-	msm8960_init_hsic();
-	msm8960_init_cam();
-	msm8960_init_mmc();
-	acpuclk_init(&acpuclk_8960_soc_data);
-	if (machine_is_msm8960_liquid())
-		mxt_init_hw_liquid();
-	register_i2c_devices();
-	msm_fb_add_devices();
-	slim_register_board_info(msm_slim_devices,
-		ARRAY_SIZE(msm_slim_devices));
-	msm8960_init_dsps();
-	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
-	msm_pm_set_rpm_wakeup_irq(RPM_APCC_CPU0_WAKE_UP_IRQ);
-	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
-				msm_pm_data);
-	change_memory_power = &msm8960_change_memory_power;
-	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
-
-	if (PLATFORM_IS_CHARM25())
-		platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
-}
-
-MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
-	.map_io = msm8960_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_sim_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
-	.map_io = msm8960_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_rumi3_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-MACHINE_START(MSM8960_CDP, "QCT MSM8960 CDP")
-	.map_io = msm8960_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_cdp_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-MACHINE_START(MSM8960_MTP, "QCT MSM8960 MTP")
-	.map_io = msm8960_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_cdp_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-MACHINE_START(MSM8960_FLUID, "QCT MSM8960 FLUID")
-	.map_io = msm8960_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_cdp_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-MACHINE_START(MSM8960_LIQUID, "QCT MSM8960 LIQUID")
-	.map_io = msm8960_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_cdp_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-#ifdef CONFIG_ARCH_MSM8930
-MACHINE_START(MSM8930_CDP, "QCT MSM8930 CDP")
-	.map_io = msm8930_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_cdp_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-MACHINE_START(MSM8930_MTP, "QCT MSM8930 MTP")
-	.map_io = msm8930_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_cdp_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-
-MACHINE_START(MSM8930_FLUID, "QCT MSM8930 FLUID")
-	.map_io = msm8930_map_io,
-	.reserve = msm8960_reserve,
-	.init_irq = msm8960_init_irq,
-	.timer = &msm_timer,
-	.init_machine = msm8960_cdp_init,
-	.init_early = msm8960_allocate_memory_regions,
-	.init_very_early = msm8960_early_memory,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-msm/board-msm8960.h b/arch/arm/mach-msm/board-msm8960.h
deleted file mode 100644
index 1cfcfdd..0000000
--- a/arch/arm/mach-msm/board-msm8960.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright (c) 2011, 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 __ARCH_ARM_MACH_MSM_BOARD_MSM8960_H
-#define __ARCH_ARM_MACH_MSM_BOARD_MSM8960_H
-
-#include <mach/irqs.h>
-#include <mach/rpm-regulator.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
-
-/* Macros assume PMIC GPIOs and MPPs start at 1 */
-#define PM8921_GPIO_BASE		NR_GPIO_IRQS
-#define PM8921_GPIO_PM_TO_SYS(pm_gpio)	(pm_gpio - 1 + PM8921_GPIO_BASE)
-#define PM8921_MPP_BASE			(PM8921_GPIO_BASE + PM8921_NR_GPIOS)
-#define PM8921_MPP_PM_TO_SYS(pm_gpio)	(pm_gpio - 1 + PM8921_MPP_BASE)
-#define PM8921_IRQ_BASE			(NR_MSM_IRQS + NR_GPIO_IRQS)
-
-extern struct pm8921_regulator_platform_data
-	msm_pm8921_regulator_pdata[] __devinitdata;
-
-extern int msm_pm8921_regulator_pdata_len __devinitdata;
-
-#define GPIO_VREG_ID_EXT_5V		0
-#define GPIO_VREG_ID_EXT_L2		1
-#define GPIO_VREG_ID_EXT_3P3V		2
-
-extern struct gpio_regulator_platform_data
-	msm_gpio_regulator_pdata[] __devinitdata;
-
-extern struct regulator_init_data msm_saw_regulator_pdata_s5;
-extern struct regulator_init_data msm_saw_regulator_pdata_s6;
-
-extern struct rpm_regulator_platform_data msm_rpm_regulator_pdata __devinitdata;
-
-#endif
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index c22d54c..3038ff0 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -144,6 +144,10 @@
 #define DSPS_PIL_GENERIC_NAME		"dsps"
 #define DSPS_PIL_FLUID_NAME		"dsps_fluid"
 
+#ifdef CONFIG_ION_MSM
+static struct platform_device ion_dev;
+#endif
+
 enum {
 	GPIO_EXPANDER_IRQ_BASE  = PM8901_IRQ_BASE + NR_PMIC8901_IRQS,
 	GPIO_EXPANDER_GPIO_BASE = PM8901_GPIO_BASE + PM8901_MPPS,
@@ -1523,7 +1527,7 @@
 
 
 #endif
-	
+
 #ifdef CONFIG_MSM_VPE
 static struct resource msm_vpe_resources[] = {
 	{
@@ -2618,7 +2622,7 @@
 #define MSM_FB_EXT_BUFT_SIZE	0
 #endif
 
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+#ifdef CONFIG_FB_MSM_OVERLAY0_WRITEBACK
 /* width x height x 3 bpp x 2 frame buffer */
 #define MSM_FB_WRITEBACK_SIZE (1024 * 600 * 3 * 2)
 #define MSM_FB_WRITEBACK_OFFSET  \
@@ -2657,7 +2661,7 @@
 #define MSM_SMI_SIZE          0x4000000
 
 #define KERNEL_SMI_BASE       (MSM_SMI_BASE)
-#define KERNEL_SMI_SIZE       0x300000
+#define KERNEL_SMI_SIZE       0x600000
 
 #define USER_SMI_BASE         (KERNEL_SMI_BASE + KERNEL_SMI_SIZE)
 #define USER_SMI_SIZE         (MSM_SMI_SIZE - KERNEL_SMI_SIZE)
@@ -5158,7 +5162,7 @@
 };
 
 #ifdef CONFIG_ION_MSM
-struct ion_platform_data ion_pdata = {
+static struct ion_platform_data ion_pdata = {
 	.nr = MSM_ION_HEAP_NUM,
 	.heaps = {
 		{
@@ -5197,7 +5201,7 @@
 	}
 };
 
-struct platform_device ion_dev = {
+static struct platform_device ion_dev = {
 	.name = "ion-msm",
 	.id = 1,
 	.dev = { .platform_data = &ion_pdata },
@@ -5781,7 +5785,7 @@
 
 static struct pm8xxx_pwrkey_platform_data pm8058_pwrkey_pdata = {
 	.pull_up		= 1,
-	.kpd_trigger_delay_us   = 970,
+	.kpd_trigger_delay_us   = 15625,
 	.wakeup			= 1,
 };
 
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index d192faf..91bb455 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -77,6 +77,7 @@
 	/* FM Platform power and shutdown routines */
 #define FPGA_MSM_CNTRL_REG2 0x90008010
 
+#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
 static void config_pcm_i2s_mode(int mode)
 {
 	void __iomem *cfg_ptr;
@@ -401,6 +402,7 @@
 	.is_fm_soc_i2s_master = true,
 	.config_i2s_gpio = msm_bahama_setup_pcm_i2s,
 };
+#endif
 
 static struct platform_device msm_wlan_ar6000_pm_device = {
 	.name           = "wlan_ar6000_pm_dev",
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index a478b6f..100689b 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -2316,7 +2316,7 @@
 static DEFINE_CLK_PCOM(p_grp_2d_clk, GRP_2D_CLK, CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(p_grp_2d_p_clk, GRP_2D_P_CLK, CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(p_hdmi_clk, HDMI_CLK, CLKFLAG_SKIP_AUTO_OFF);
-static DEFINE_CLK_PCOM(p_jpeg_clk, JPEG_CLK, 0);
+static DEFINE_CLK_PCOM(p_jpeg_clk, JPEG_CLK, CLKFLAG_MIN);
 static DEFINE_CLK_PCOM(p_jpeg_p_clk, JPEG_P_CLK, 0);
 static DEFINE_CLK_PCOM(p_lpa_codec_clk, LPA_CODEC_CLK, CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(p_lpa_core_clk, LPA_CORE_CLK, CLKFLAG_SKIP_AUTO_OFF);
@@ -2386,7 +2386,7 @@
 static DEFINE_CLK_PCOM(p_csi0_clk, CSI0_CLK, CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(p_csi0_vfe_clk, CSI0_VFE_CLK, CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(p_csi0_p_clk, CSI0_P_CLK, CLKFLAG_SKIP_AUTO_OFF);
-static DEFINE_CLK_PCOM(p_mdp_clk, MDP_CLK, 0);
+static DEFINE_CLK_PCOM(p_mdp_clk, MDP_CLK, CLKFLAG_MIN);
 static DEFINE_CLK_PCOM(p_mfc_clk, MFC_CLK, CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(p_mfc_div2_clk, MFC_DIV2_CLK, CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(p_mfc_p_clk, MFC_P_CLK, CLKFLAG_SKIP_AUTO_OFF);
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index a4c8b2a2..3214be5 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4480,22 +4480,8 @@
 		}, \
 	}
 
-#define F_AIF_BIT(d, s) \
-	{ \
-		.freq_hz = d, \
-		.ns_val = (BVAL(14, 14, s) | BVAL(13, 10, (d-1))) \
-	}
-static struct clk_freq_tbl clk_tbl_aif_bit[] = {
-	F_AIF_BIT(0, 1),  /* Use external clock. */
-	F_AIF_BIT(1, 0),  F_AIF_BIT(2, 0),  F_AIF_BIT(3, 0),  F_AIF_BIT(4, 0),
-	F_AIF_BIT(5, 0),  F_AIF_BIT(6, 0),  F_AIF_BIT(7, 0),  F_AIF_BIT(8, 0),
-	F_AIF_BIT(9, 0),  F_AIF_BIT(10, 0), F_AIF_BIT(11, 0), F_AIF_BIT(12, 0),
-	F_AIF_BIT(13, 0), F_AIF_BIT(14, 0), F_AIF_BIT(15, 0), F_AIF_BIT(16, 0),
-	F_END
-};
-
 #define CLK_AIF_BIT(i, ns, h_r) \
-	struct rcg_clk i##_clk = { \
+	struct cdiv_clk i##_clk = { \
 		.b = { \
 			.ctl_reg = ns, \
 			.en_mask = BIT(15), \
@@ -4503,35 +4489,18 @@
 			.halt_check = DELAY, \
 		}, \
 		.ns_reg = ns, \
-		.ns_mask = BM(14, 10), \
-		.set_rate = set_rate_nop, \
-		.freq_tbl = clk_tbl_aif_bit, \
-		.current_freq = &rcg_dummy_freq, \
+		.ext_mask = BIT(14), \
+		.div_offset = 10, \
+		.max_div = 16, \
 		.c = { \
 			.dbg_name = #i "_clk", \
-			.ops = &clk_ops_rcg_8960, \
+			.ops = &clk_ops_cdiv, \
 			CLK_INIT(i##_clk.c), \
 		}, \
 	}
 
-#define F_AIF_BIT_D(d, s) \
-	{ \
-		.freq_hz = d, \
-		.ns_val = (BVAL(18, 18, s) | BVAL(17, 10, (d-1))) \
-	}
-static struct clk_freq_tbl clk_tbl_aif_bit_div[] = {
-	F_AIF_BIT_D(0, 1),  /* Use external clock. */
-	F_AIF_BIT_D(1, 0), F_AIF_BIT_D(2, 0), F_AIF_BIT_D(3, 0),
-	F_AIF_BIT_D(4, 0), F_AIF_BIT_D(5, 0), F_AIF_BIT_D(6, 0),
-	F_AIF_BIT_D(7, 0), F_AIF_BIT_D(8, 0), F_AIF_BIT_D(9, 0),
-	F_AIF_BIT_D(10, 0), F_AIF_BIT_D(11, 0), F_AIF_BIT_D(12, 0),
-	F_AIF_BIT_D(13, 0), F_AIF_BIT_D(14, 0), F_AIF_BIT_D(15, 0),
-	F_AIF_BIT_D(16, 0),
-	F_END
-};
-
 #define CLK_AIF_BIT_DIV(i, ns, h_r) \
-	struct rcg_clk i##_clk = { \
+	struct cdiv_clk i##_clk = { \
 		.b = { \
 			.ctl_reg = ns, \
 			.en_mask = BIT(19), \
@@ -4539,13 +4508,12 @@
 			.halt_check = ENABLE, \
 		}, \
 		.ns_reg = ns, \
-		.ns_mask = BM(18, 10), \
-		.set_rate = set_rate_nop, \
-		.freq_tbl = clk_tbl_aif_bit_div, \
-		.current_freq = &rcg_dummy_freq, \
+		.ext_mask = BIT(18), \
+		.div_offset = 10, \
+		.max_div = 256, \
 		.c = { \
 			.dbg_name = #i "_clk", \
-			.ops = &clk_ops_rcg_8960, \
+			.ops = &clk_ops_cdiv, \
 			CLK_INIT(i##_clk.c), \
 		}, \
 	}
@@ -5144,7 +5112,7 @@
 	CLK_LOOKUP("core_clk",		gsbi7_qup_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		pdm_clk.c,		NULL),
 	CLK_LOOKUP("pmem_clk",		pmem_clk.c,		NULL),
-	CLK_DUMMY("core_clk",           PRNG_CLK,               NULL, OFF),
+	CLK_DUMMY("core_clk",           PRNG_CLK,	"msm_rng.0", OFF),
 	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"),
@@ -5224,7 +5192,7 @@
 	CLK_LOOKUP("dsi_esc_clk",	dsi2_esc_clk.c,		NULL),
 	CLK_DUMMY("rgb_tv_clk",		RGB_TV_CLK,		NULL, OFF),
 	CLK_DUMMY("npl_tv_clk",		NPL_TV_CLK,		NULL, OFF),
-	CLK_LOOKUP("core_clk",		gfx3d_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.c, "footswitch-8x60.2"),
 	CLK_LOOKUP("iface_clk",         vcap_p_clk.c,           NULL),
@@ -5268,7 +5236,7 @@
 	CLK_LOOKUP("dsi_s_pclk",	dsi1_s_p_clk.c,		NULL),
 	CLK_LOOKUP("dsi_m_pclk",	dsi2_m_p_clk.c,		NULL),
 	CLK_LOOKUP("dsi_s_pclk",	dsi2_s_p_clk.c,		NULL),
-	CLK_LOOKUP("iface_clk",		gfx3d_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,		NULL),
 	CLK_LOOKUP("slave_iface_clk",	hdmi_s_p_clk.c,		NULL),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 17052ae..662e9a6 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3106,22 +3106,8 @@
 		}, \
 	}
 
-#define F_AIF_BIT(d, s) \
-	{ \
-		.freq_hz = d, \
-		.ns_val = (BVAL(14, 14, s) | BVAL(13, 10, (d-1))) \
-	}
-static struct clk_freq_tbl clk_tbl_aif_bit[] = {
-	F_AIF_BIT(0, 1),  /* Use external clock. */
-	F_AIF_BIT(1, 0),  F_AIF_BIT(2, 0),  F_AIF_BIT(3, 0),  F_AIF_BIT(4, 0),
-	F_AIF_BIT(5, 0),  F_AIF_BIT(6, 0),  F_AIF_BIT(7, 0),  F_AIF_BIT(8, 0),
-	F_AIF_BIT(9, 0),  F_AIF_BIT(10, 0), F_AIF_BIT(11, 0), F_AIF_BIT(12, 0),
-	F_AIF_BIT(13, 0), F_AIF_BIT(14, 0), F_AIF_BIT(15, 0), F_AIF_BIT(16, 0),
-	F_END
-};
-
 #define CLK_AIF_BIT(i, ns, h_r) \
-	struct rcg_clk i##_clk = { \
+	struct cdiv_clk i##_clk = { \
 		.b = { \
 			.ctl_reg = ns, \
 			.en_mask = BIT(15), \
@@ -3129,13 +3115,12 @@
 			.halt_check = DELAY, \
 		}, \
 		.ns_reg = ns, \
-		.ns_mask = BM(14, 10), \
-		.set_rate = set_rate_nop, \
-		.freq_tbl = clk_tbl_aif_bit, \
-		.current_freq = &rcg_dummy_freq, \
+		.ext_mask = BIT(14), \
+		.div_offset = 10, \
+		.max_div = 16, \
 		.c = { \
 			.dbg_name = #i "_clk", \
-			.ops = &clk_ops_rcg_8x60, \
+			.ops = &clk_ops_cdiv, \
 			CLK_INIT(i##_clk.c), \
 		}, \
 	}
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index c8212a3..e47981e 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1211,22 +1211,8 @@
 		}, \
 	}
 
-#define F_AIF_BIT(d, s) \
-	{ \
-		.freq_hz = d, \
-		.ns_val = (BVAL(14, 14, s) | BVAL(13, 10, (d-1))) \
-	}
-static struct clk_freq_tbl clk_tbl_aif_bit[] = {
-	F_AIF_BIT(0, 1),  /* Use external clock. */
-	F_AIF_BIT(1, 0),  F_AIF_BIT(2, 0),  F_AIF_BIT(3, 0),  F_AIF_BIT(4, 0),
-	F_AIF_BIT(5, 0),  F_AIF_BIT(6, 0),  F_AIF_BIT(7, 0),  F_AIF_BIT(8, 0),
-	F_AIF_BIT(9, 0),  F_AIF_BIT(10, 0), F_AIF_BIT(11, 0), F_AIF_BIT(12, 0),
-	F_AIF_BIT(13, 0), F_AIF_BIT(14, 0), F_AIF_BIT(15, 0), F_AIF_BIT(16, 0),
-	F_END
-};
-
 #define CLK_AIF_BIT(i, ns, h_r) \
-	struct rcg_clk i##_clk = { \
+	struct cdiv_clk i##_clk = { \
 		.b = { \
 			.ctl_reg = ns, \
 			.en_mask = BIT(15), \
@@ -1234,35 +1220,18 @@
 			.halt_check = DELAY, \
 		}, \
 		.ns_reg = ns, \
-		.ns_mask = BM(14, 10), \
-		.set_rate = set_rate_nop, \
-		.freq_tbl = clk_tbl_aif_bit, \
-		.current_freq = &rcg_dummy_freq, \
+		.ext_mask = BIT(14), \
+		.div_offset = 10, \
+		.max_div = 16, \
 		.c = { \
 			.dbg_name = #i "_clk", \
-			.ops = &clk_ops_rcg_9615, \
+			.ops = &clk_ops_cdiv, \
 			CLK_INIT(i##_clk.c), \
 		}, \
 	}
 
-#define F_AIF_BIT_D(d, s) \
-	{ \
-		.freq_hz = d, \
-		.ns_val = (BVAL(18, 18, s) | BVAL(17, 10, (d-1))) \
-	}
-static struct clk_freq_tbl clk_tbl_aif_bit_div[] = {
-	F_AIF_BIT_D(0, 1),  /* Use external clock. */
-	F_AIF_BIT_D(1, 0), F_AIF_BIT_D(2, 0), F_AIF_BIT_D(3, 0),
-	F_AIF_BIT_D(4, 0), F_AIF_BIT_D(5, 0), F_AIF_BIT_D(6, 0),
-	F_AIF_BIT_D(7, 0), F_AIF_BIT_D(8, 0), F_AIF_BIT_D(9, 0),
-	F_AIF_BIT_D(10, 0), F_AIF_BIT_D(11, 0), F_AIF_BIT_D(12, 0),
-	F_AIF_BIT_D(13, 0), F_AIF_BIT_D(14, 0), F_AIF_BIT_D(15, 0),
-	F_AIF_BIT_D(16, 0),
-	F_END
-};
-
 #define CLK_AIF_BIT_DIV(i, ns, h_r) \
-	struct rcg_clk i##_clk = { \
+	struct cdiv_clk i##_clk = { \
 		.b = { \
 			.ctl_reg = ns, \
 			.en_mask = BIT(19), \
@@ -1270,13 +1239,12 @@
 			.halt_check = ENABLE, \
 		}, \
 		.ns_reg = ns, \
-		.ns_mask = BM(18, 10), \
-		.set_rate = set_rate_nop, \
-		.freq_tbl = clk_tbl_aif_bit_div, \
-		.current_freq = &rcg_dummy_freq, \
+		.ext_mask = BIT(18), \
+		.div_offset = 10, \
+		.max_div = 256, \
 		.c = { \
 			.dbg_name = #i "_clk", \
-			.ops = &clk_ops_rcg_9615, \
+			.ops = &clk_ops_cdiv, \
 			CLK_INIT(i##_clk.c), \
 		}, \
 	}
@@ -1679,14 +1647,10 @@
 	CLK_LOOKUP("core_clk",		gp1_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		gp2_clk.c,	NULL),
 
-	CLK_LOOKUP("core_clk", gsbi1_uart_clk.c, NULL),
-	CLK_LOOKUP("core_clk", gsbi2_uart_clk.c, NULL),
 	CLK_LOOKUP("core_clk", gsbi3_uart_clk.c, NULL),
 	CLK_LOOKUP("core_clk", gsbi4_uart_clk.c, "msm_serial_hsl.0"),
 	CLK_LOOKUP("core_clk", gsbi5_uart_clk.c, NULL),
 
-	CLK_LOOKUP("core_clk",	gsbi1_qup_clk.c, NULL),
-	CLK_LOOKUP("core_clk",	gsbi2_qup_clk.c, NULL),
 	CLK_LOOKUP("core_clk",	gsbi3_qup_clk.c, "spi_qsd.0"),
 	CLK_LOOKUP("core_clk",	gsbi4_qup_clk.c, NULL),
 	CLK_LOOKUP("core_clk",	gsbi5_qup_clk.c, "qup_i2c.0"),
@@ -1700,8 +1664,6 @@
 	CLK_LOOKUP("core_clk",		ce1_core_clk.c,		NULL),
 	CLK_LOOKUP("dma_bam_pclk",	dma_bam_p_clk.c,	NULL),
 
-	CLK_LOOKUP("iface_clk",	gsbi1_p_clk.c, NULL),
-	CLK_LOOKUP("iface_clk",	gsbi2_p_clk.c, NULL),
 	CLK_LOOKUP("iface_clk",	gsbi3_p_clk.c, "spi_qsd.0"),
 	CLK_LOOKUP("iface_clk",	gsbi4_p_clk.c, "msm_serial_hsl.0"),
 	CLK_LOOKUP("iface_clk",	gsbi5_p_clk.c, "qup_i2c.0"),
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
index d1a257d..dd31bd7 100644
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -87,7 +87,7 @@
 static DEFINE_CLK_PCOM(icodec_tx_clk,	ICODEC_TX_CLK,	CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(imem_clk,	IMEM_CLK,	0);
 static DEFINE_CLK_PCOM(mdc_clk,		MDC_CLK,	CLKFLAG_SKIP_AUTO_OFF);
-static DEFINE_CLK_PCOM(mdp_clk,		MDP_CLK,	0);
+static DEFINE_CLK_PCOM(mdp_clk,		MDP_CLK,	CLKFLAG_MIN);
 static DEFINE_CLK_PCOM(mdp_lcdc_pad_pclk_clk, MDP_LCDC_PAD_PCLK_CLK,
 		CLKFLAG_SKIP_AUTO_OFF);
 static DEFINE_CLK_PCOM(mdp_lcdc_pclk_clk, MDP_LCDC_PCLK_CLK,
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index afc2649..7420bc0 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -581,6 +581,23 @@
 	.id		= -1,
 };
 
+#ifdef CONFIG_HW_RANDOM_MSM
+/* PRNG device */
+#define MSM_PRNG_PHYS           0x1A500000
+static struct resource rng_resources = {
+	.flags = IORESOURCE_MEM,
+	.start = MSM_PRNG_PHYS,
+	.end   = MSM_PRNG_PHYS + SZ_512 - 1,
+};
+
+struct platform_device apq8064_device_rng = {
+	.name          = "msm_rng",
+	.id            = 0,
+	.num_resources = 1,
+	.resource      = &rng_resources,
+};
+#endif
+
 static struct clk_lookup msm_clocks_8064_dummy[] = {
 	CLK_DUMMY("pll2",		PLL2,		NULL, 0),
 	CLK_DUMMY("pll8",		PLL8,		NULL, 0),
@@ -625,7 +642,7 @@
 	CLK_DUMMY("core_clk",		GSBI7_QUP_CLK,		NULL, OFF),
 	CLK_DUMMY("core_clk",		PDM_CLK,		NULL, OFF),
 	CLK_DUMMY("mem_clk",		PMEM_CLK,		NULL, OFF),
-	CLK_DUMMY("core_clk",		PRNG_CLK,		NULL, OFF),
+	CLK_DUMMY("core_clk",		PRNG_CLK,	"msm_rng.0", OFF),
 	CLK_DUMMY("core_clk",		SDC1_CLK,		NULL, OFF),
 	CLK_DUMMY("core_clk",		SDC2_CLK,		NULL, OFF),
 	CLK_DUMMY("core_clk",		SDC3_CLK,		NULL, OFF),
@@ -688,7 +705,7 @@
 	CLK_DUMMY("dsi_esc_clk",	DSI2_ESC_CLK,		NULL, OFF),
 	CLK_DUMMY("core_clk",		VCAP_CLK,		NULL, OFF),
 	CLK_DUMMY("npl_clk",		VCAP_NPL_CLK,		NULL, OFF),
-	CLK_DUMMY("core_clk",		GFX3D_CLK,		NULL, OFF),
+	CLK_DUMMY("core_clk",		GFX3D_CLK,	"kgsl-3d0.0", OFF),
 	CLK_DUMMY("ijpeg_clk",		IJPEG_CLK,		NULL, OFF),
 	CLK_DUMMY("mem_clk",		IMEM_CLK,		NULL, OFF),
 	CLK_DUMMY("core_clk",		JPEGD_CLK,		NULL, OFF),
@@ -727,7 +744,7 @@
 	CLK_DUMMY("mdp_p2clk",          MDP_P2CLK,              NULL, OFF),
 	CLK_DUMMY("dsi2_pixel_clk",     DSI2_PIXEL_CLK,         NULL, OFF),
 	CLK_DUMMY("lvds_ref_clk",       LVDS_REF_CLK,           NULL, OFF),
-	CLK_DUMMY("iface_clk",		GFX3D_P_CLK,		NULL, OFF),
+	CLK_DUMMY("iface_clk",		GFX3D_P_CLK,	"kgsl-3d0.0", OFF),
 	CLK_DUMMY("master_iface_clk",	HDMI_M_P_CLK,	"hdmi_msm.1", OFF),
 	CLK_DUMMY("slave_iface_clk",	HDMI_S_P_CLK,	"hdmi_msm.1", OFF),
 	CLK_DUMMY("ijpeg_pclk",		IJPEG_P_CLK,		NULL, OFF),
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 2add8f9..e814b4e 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -30,6 +30,7 @@
 #include <mach/rpm.h>
 #include <mach/msm_bus_board.h>
 #include <mach/msm_memtypes.h>
+#include <mach/msm_xo.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
 #include "clock.h"
@@ -38,6 +39,8 @@
 #include "footswitch.h"
 #include "msm_watchdog.h"
 #include "rpm_stats.h"
+#include "pil-q6v4.h"
+#include "scm-pas.h"
 
 #ifdef CONFIG_MSM_MPM
 #include "mpm.h"
@@ -815,6 +818,113 @@
 	},
 };
 
+#define MSM_LPASS_QDSP6SS_PHYS	0x28800000
+#define SFAB_LPASS_Q6_ACLK_CTL	(MSM_CLK_CTL_BASE + 0x23A0)
+
+static struct resource msm_8960_q6_lpass_resources[] = {
+	{
+		.start  = MSM_LPASS_QDSP6SS_PHYS,
+		.end    = MSM_LPASS_QDSP6SS_PHYS + SZ_256 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct pil_q6v4_pdata msm_8960_q6_lpass_data = {
+	.strap_tcm_base  = 0x01460000,
+	.strap_ahb_upper = 0x00290000,
+	.strap_ahb_lower = 0x00000280,
+	.aclk_reg = SFAB_LPASS_Q6_ACLK_CTL,
+	.xo_id = MSM_XO_PXO,
+	.name = "q6",
+	.pas_id = PAS_Q6,
+	.bus_port = MSM_BUS_MASTER_LPASS_PROC,
+};
+
+struct platform_device msm_8960_q6_lpass = {
+	.name = "pil_qdsp6v4",
+	.id = 0,
+	.num_resources  = ARRAY_SIZE(msm_8960_q6_lpass_resources),
+	.resource       = msm_8960_q6_lpass_resources,
+	.dev.platform_data = &msm_8960_q6_lpass_data,
+};
+
+#define MSM_MSS_ENABLE_PHYS	0x08B00000
+#define MSM_FW_QDSP6SS_PHYS	0x08800000
+#define MSS_Q6FW_JTAG_CLK_CTL	(MSM_CLK_CTL_BASE + 0x2C6C)
+#define SFAB_MSS_Q6_FW_ACLK_CTL (MSM_CLK_CTL_BASE + 0x2044)
+
+static struct resource msm_8960_q6_mss_fw_resources[] = {
+	{
+		.start  = MSM_FW_QDSP6SS_PHYS,
+		.end    = MSM_FW_QDSP6SS_PHYS + SZ_256 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = MSM_MSS_ENABLE_PHYS,
+		.end    = MSM_MSS_ENABLE_PHYS + 4 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct pil_q6v4_pdata msm_8960_q6_mss_fw_data = {
+	.strap_tcm_base  = 0x00400000,
+	.strap_ahb_upper = 0x00090000,
+	.strap_ahb_lower = 0x00000080,
+	.aclk_reg = SFAB_MSS_Q6_FW_ACLK_CTL,
+	.jtag_clk_reg = MSS_Q6FW_JTAG_CLK_CTL,
+	.xo_id = MSM_XO_TCXO_D0,
+	.name = "modem_fw",
+	.depends = "q6",
+	.pas_id = PAS_MODEM_FW,
+	.bus_port = MSM_BUS_MASTER_MSS_FW_PROC,
+};
+
+struct platform_device msm_8960_q6_mss_fw = {
+	.name = "pil_qdsp6v4",
+	.id = 1,
+	.num_resources  = ARRAY_SIZE(msm_8960_q6_mss_fw_resources),
+	.resource       = msm_8960_q6_mss_fw_resources,
+	.dev.platform_data = &msm_8960_q6_mss_fw_data,
+};
+
+#define MSM_SW_QDSP6SS_PHYS	0x08900000
+#define SFAB_MSS_Q6_SW_ACLK_CTL	(MSM_CLK_CTL_BASE + 0x2040)
+#define MSS_Q6SW_JTAG_CLK_CTL	(MSM_CLK_CTL_BASE + 0x2C68)
+
+static struct resource msm_8960_q6_mss_sw_resources[] = {
+	{
+		.start  = MSM_SW_QDSP6SS_PHYS,
+		.end    = MSM_SW_QDSP6SS_PHYS + SZ_256 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = MSM_MSS_ENABLE_PHYS,
+		.end    = MSM_MSS_ENABLE_PHYS + 4 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct pil_q6v4_pdata msm_8960_q6_mss_sw_data = {
+	.strap_tcm_base  = 0x00420000,
+	.strap_ahb_upper = 0x00090000,
+	.strap_ahb_lower = 0x00000080,
+	.aclk_reg = SFAB_MSS_Q6_SW_ACLK_CTL,
+	.jtag_clk_reg = MSS_Q6SW_JTAG_CLK_CTL,
+	.xo_id = MSM_XO_TCXO_D0,
+	.name = "modem",
+	.depends = "modem_fw",
+	.pas_id = PAS_MODEM_SW,
+	.bus_port = MSM_BUS_MASTER_MSS_SW_PROC,
+};
+
+struct platform_device msm_8960_q6_mss_sw = {
+	.name = "pil_qdsp6v4",
+	.id = 2,
+	.num_resources  = ARRAY_SIZE(msm_8960_q6_mss_sw_resources),
+	.resource       = msm_8960_q6_mss_sw_resources,
+	.dev.platform_data = &msm_8960_q6_mss_sw_data,
+};
+
 struct platform_device msm_device_smd = {
 	.name		= "msm_smd",
 	.id		= -1,
@@ -1217,18 +1327,6 @@
 		.flags  = IORESOURCE_IO,
 	},
 	{
-		.name   = "spi_cs",
-		.start  = 8,
-		.end    = 8,
-		.flags  = IORESOURCE_IO,
-	},
-	{
-		.name   = "spi_cs1",
-		.start  = 14,
-		.end    = 14,
-		.flags  = IORESOURCE_IO,
-	},
-	{
 		.name   = "spi_miso",
 		.start  = 7,
 		.end    = 7,
@@ -1240,6 +1338,18 @@
 		.end    = 6,
 		.flags  = IORESOURCE_IO,
 	},
+	{
+		.name   = "spi_cs",
+		.start  = 8,
+		.end    = 8,
+		.flags  = IORESOURCE_IO,
+	},
+	{
+		.name   = "spi_cs1",
+		.start  = 14,
+		.end    = 14,
+		.flags  = IORESOURCE_IO,
+	},
 };
 
 struct platform_device msm8960_device_qup_spi_gsbi1 = {
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index d89c9d7..b9ff604 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -949,12 +949,6 @@
 		.flags  = IORESOURCE_IO,
 	},
 	{
-		.name   = "spi_cs",
-		.start  = 35,
-		.end    = 35,
-		.flags  = IORESOURCE_IO,
-	},
-	{
 		.name   = "spi_miso",
 		.start  = 34,
 		.end    = 34,
@@ -966,6 +960,12 @@
 		.end    = 33,
 		.flags  = IORESOURCE_IO,
 	},
+	{
+		.name   = "spi_cs",
+		.start  = 35,
+		.end    = 35,
+		.flags  = IORESOURCE_IO,
+	},
 };
 
 /* Use GSBI1 QUP for SPI-0 */
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index a95d0b6..147f01d 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -172,6 +172,10 @@
 extern struct platform_device msm_cpudai_afe_02_tx;
 extern struct platform_device msm_pcm_afe;
 
+extern struct platform_device msm_8960_q6_lpass;
+extern struct platform_device msm_8960_q6_mss_fw;
+extern struct platform_device msm_8960_q6_mss_sw;
+
 extern struct platform_device *msm_footswitch_devices[];
 extern unsigned msm_num_footswitch_devices;
 
@@ -199,10 +203,10 @@
 
 extern struct platform_device led_pdev;
 
-extern struct platform_device ion_dev;
 extern struct platform_device msm_rpm_device;
 extern struct platform_device msm_rpm_stat_device;
 extern struct platform_device msm_device_rng;
+extern struct platform_device apq8064_device_rng;
 
 #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
 		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 98447fa..a8e2449 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -256,6 +256,14 @@
 	udelay(RESET_DELAY_US);
 
 	/*
+	 * Return clocks to their state before this function. For robustness
+	 * if memory-retention across collapses is required, clocks should
+	 * be disabled before asserting the clamps. Assuming clocks were off
+	 * before entering footswitch_disable(), this will be true.
+	 */
+	restore_clocks(fs);
+
+	/*
 	 * Clamp the I/O ports of the core to ensure the values
 	 * remain fixed while the core is collapsed.
 	 */
@@ -266,9 +274,6 @@
 	regval &= ~ENABLE_BIT;
 	writel_relaxed(regval, fs->gfs_ctl_reg);
 
-	/* Return clocks to their state before this function. */
-	restore_clocks(fs);
-
 	fs->is_enabled = false;
 
 	return rc;
diff --git a/arch/arm/mach-msm/include/mach/bam_dmux.h b/arch/arm/mach-msm/include/mach/bam_dmux.h
index a2b0126..fb70da4 100644
--- a/arch/arm/mach-msm/include/mach/bam_dmux.h
+++ b/arch/arm/mach-msm/include/mach/bam_dmux.h
@@ -59,6 +59,10 @@
 int msm_bam_dmux_write(uint32_t id, struct sk_buff *skb);
 
 void msm_bam_dmux_kickoff_ul_wakeup(void);
+
+int msm_bam_dmux_is_ch_full(uint32_t id);
+
+int msm_bam_dmux_is_ch_low(uint32_t id);
 #else
 int msm_bam_dmux_open(uint32_t id, void *priv,
 		       void (*notify)(void *priv, int event_type,
@@ -80,5 +84,15 @@
 void msm_bam_dmux_kickoff_ul_wakeup(void)
 {
 }
+
+int msm_bam_dmux_is_ch_full(uint32_t id)
+{
+	return -ENODEV;
+}
+
+int msm_bam_dmux_is_ch_low(uint32_t id)
+{
+	return -ENODEV;
+}
 #endif
 #endif /* _BAM_DMUX_H */
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 1745f26..b41398e 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -635,7 +635,6 @@
 void msm_camio_clk_rate_set(int rate);
 int msm_camio_vfe_clk_rate_set(int rate);
 void msm_camio_clk_rate_set_2(struct clk *clk, int rate);
-void msm_camio_clk_set_min_rate(struct clk *clk, int rate);
 void msm_camio_clk_axi_rate_set(int rate);
 void msm_disable_io_gpio_clk(struct platform_device *);
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-copper.h b/arch/arm/mach-msm/include/mach/irqs-copper.h
index d019047..24da0a4 100644
--- a/arch/arm/mach-msm/include/mach/irqs-copper.h
+++ b/arch/arm/mach-msm/include/mach/irqs-copper.h
@@ -24,9 +24,6 @@
 #define GIC_PPI_START 16
 #define GIC_SPI_START 32
 
-#define INT_VGIC				(GIC_PPI_START + 0)
-#define INT_DEBUG_TIMER_EXP			(GIC_PPI_START + 1)
-#define INT_GP_TIMER_EXP			(GIC_PPI_START + 2)
 #define AVS_SVICINT				(GIC_PPI_START + 6)
 #define AVS_SVICINTSWDONE			(GIC_PPI_START + 7)
 #define INT_ARMQC_PERFMON			(GIC_PPI_START + 10)
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index f208d88..9cd73db 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -21,7 +21,7 @@
 #define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET)
 
 #define MAX_PHYSMEM_BITS 32
-#define SECTION_SIZE_BITS 29
+#define SECTION_SIZE_BITS 28
 
 /* Maximum number of Memory Regions */
 #define MAX_NR_REGIONS 4
@@ -58,8 +58,6 @@
 
 #endif
 
-#define HAS_ARCH_IO_REMAP_PFN_RANGE
-
 #ifndef __ASSEMBLY__
 void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment);
 void *allocate_contiguous_ebi(unsigned long, unsigned long, int);
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
index 57758c3..a3c9da8 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
@@ -29,18 +29,12 @@
 #define COPPER_QGIC_CPU_PHYS	0xF9002000
 #define COPPER_QGIC_CPU_SIZE	SZ_4K
 
-#define COPPER_TLMM_PHYS	0xFC4A0000
+#define COPPER_TLMM_PHYS	0xFD400000
 #define COPPER_TLMM_SIZE	SZ_16K
 
-#define COPPER_TMR_PHYS		0xF900A000
-#define COPPER_TMR_SIZE		SZ_4K
-
-#define COPPER_TMR0_PHYS	0xF908A000
-#define COPPER_TMR0_SIZE	SZ_4K
-
 #ifdef CONFIG_DEBUG_MSMCOPPER_UART
-#define MSM_DEBUG_UART_BASE	IOMEM(0xFA782000)
-#define MSM_DEBUG_UART_PHYS	0xF9682000
+#define MSM_DEBUG_UART_BASE	IOMEM(0xFA71E000)
+#define MSM_DEBUG_UART_PHYS	0xF991E000
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 0c2cd4b..6d45b7d 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -209,7 +209,13 @@
 	SMEM_SMEM_LOG_MPROC_WRAP,
 	SMEM_BOOT_INFO_FOR_APPS,
 	SMEM_SMSM_SIZE_INFO,
-	SMEM_MEM_LAST = SMEM_SMSM_SIZE_INFO,
+	SMEM_SMD_LOOPBACK_REGISTER,
+	SMEM_SSR_REASON_MSS0,
+	SMEM_SSR_REASON_WCNSS0,
+	SMEM_SSR_REASON_LPASS0,
+	SMEM_SSR_REASON_DSPS0,
+	SMEM_SSR_REASON_VCODEC0,
+	SMEM_MEM_LAST = SMEM_SSR_REASON_VCODEC0,
 	SMEM_NUM_ITEMS,
 };
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
index 1f8ce68..674cfe8 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
@@ -521,6 +521,8 @@
 #define VSS_NETWORK_ID_VOIP_WV				0x00011242
 
 /* Media types */
+#define VSS_MEDIA_ID_13K_MODEM		0x00010FC1
+/* Qcelp vocoder modem format */
 #define VSS_MEDIA_ID_EVRC_MODEM		0x00010FC2
 /* 80-VF690-47 CDMA enhanced variable rate vocoder modem format. */
 #define VSS_MEDIA_ID_4GV_NB_MODEM  0x00010FC3
@@ -531,6 +533,12 @@
 /* 80-VF690-47 UMTS AMR-NB vocoder modem format. */
 #define VSS_MEDIA_ID_AMR_WB_MODEM	0x00010FC7
 /* 80-VF690-47 UMTS AMR-WB vocoder modem format. */
+#define VSS_MEDIA_ID_EFR_MODEM		0x00010FC8
+/*EFR modem format */
+#define VSS_MEDIA_ID_FR_MODEM		0x00010FC9
+/*FR modem format */
+#define VSS_MEDIA_ID_HR_MODEM		0x00010FCA
+/*HR modem format */
 #define VSS_MEDIA_ID_PCM_NB		0x00010FCB
 /* Linear PCM (16-bit, little-endian). */
 #define VSS_MEDIA_ID_PCM_WB		0x00010FCC
diff --git a/arch/arm/mach-msm/include/mach/sdio_tty.h b/arch/arm/mach-msm/include/mach/sdio_tty.h
deleted file mode 100644
index 86746b3..0000000
--- a/arch/arm/mach-msm/include/mach/sdio_tty.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2011, 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.
- */
-
-/*
- * SDIO TTY interface.
- */
-
-#ifndef __SDIO_TTY__
-#define __SDIO_TTY__
-
-/**
- * sdio_tty_init_tty - Initialize the SDIO TTY driver.
- *
- * @tty_name: tty name - identify the tty device.
- * @sdio_ch_name: channel name - identify the channel.
- * @return sdio_tty handle on success, NULL on error.
- *
- */
-void *sdio_tty_init_tty(char *tty_name, char* sdio_ch_name);
-
-/**
- * sdio_tty_uninit_tty - Uninitialize the SDIO TTY driver.
- *
- * @sdio_tty_handle: sdio_tty handle.
- * @return 0 on success, negative value on error.
- */
-int sdio_tty_uninit_tty(void *sdio_tty_handle);
-
-/**
- * sdio_tty_enable_debug_msg - Enable/Disable sdio_tty debug
- * messages.
- *
- * @enable: A flag to indicate if to enable or disable the debug
- *        messages.
- * @return 0 on success, negative value on error.
- */
-void sdio_tty_enable_debug_msg(void *sdio_tty_handle, int enable);
-
-#endif /* __SDIO_TTY__ */
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index fba6efe2..a06b9ae 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -61,6 +61,7 @@
 	MSM_CPU_7X27AA,
 	MSM_CPU_9615,
 	MSM_CPU_COPPER,
+	MSM_CPU_8627,
 };
 
 enum msm_cpu socinfo_get_msm_cpu(void);
@@ -225,7 +226,18 @@
 static inline int cpu_is_msm8930(void)
 {
 #ifdef CONFIG_ARCH_MSM8930
-	return read_msm_cpu_type() == MSM_CPU_8930;
+	return (read_msm_cpu_type() == MSM_CPU_8930) ||
+	       (read_msm_cpu_type() == MSM_CPU_8627);
+#else
+	return 0;
+#endif
+}
+
+static inline int cpu_is_msm8627(void)
+{
+/* 8930 and 8627 will share the same CONFIG_ARCH type unless otherwise needed */
+#ifdef CONFIG_ARCH_MSM8930
+	return read_msm_cpu_type() == MSM_CPU_8627;
 #else
 	return 0;
 #endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index f09c6d9..2d5b0a4 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -284,8 +284,6 @@
 	MSM_CHIP_DEVICE(QGIC_DIST, COPPER),
 	MSM_CHIP_DEVICE(QGIC_CPU, COPPER),
 	MSM_CHIP_DEVICE(TLMM, COPPER),
-	MSM_CHIP_DEVICE(TMR, COPPER),
-	MSM_CHIP_DEVICE(TMR0, COPPER),
 #ifdef CONFIG_DEBUG_MSMCOPPER_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 3d34a30..8e9cc0f 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -1938,7 +1938,6 @@
 	}
 	mutex_unlock(&port_ptr->port_rx_q_lock);
 
-	wake_lock_destroy(&port_ptr->port_rx_wake_lock);
 	if (port_ptr->type == SERVER_PORT) {
 		server = msm_ipc_router_lookup_server(
 				port_ptr->port_name.service,
@@ -1962,6 +1961,7 @@
 		mutex_unlock(&control_ports_lock);
 	}
 
+	wake_lock_destroy(&port_ptr->port_rx_wake_lock);
 	kfree(port_ptr);
 	return 0;
 }
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 00f315d..31fbd43 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -38,17 +38,6 @@
 #include <mach/socinfo.h>
 #include <../../mm/mm.h>
 
-int arch_io_remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
-			    unsigned long pfn, unsigned long size, pgprot_t prot)
-{
-	unsigned long pfn_addr = pfn << PAGE_SHIFT;
-	if ((pfn_addr >= 0x88000000) && (pfn_addr < 0xD0000000)) {
-		prot = pgprot_device(prot);
-		pr_debug("remapping device %lx\n", prot);
-	}
-	return remap_pfn_range(vma, addr, pfn, size, prot);
-}
-
 void *strongly_ordered_page;
 char strongly_ordered_mem[PAGE_SIZE*2-4];
 
diff --git a/arch/arm/mach-msm/modem-8960.c b/arch/arm/mach-msm/modem-8960.c
index f0aa13c..7345a89 100644
--- a/arch/arm/mach-msm/modem-8960.c
+++ b/arch/arm/mach-msm/modem-8960.c
@@ -149,9 +149,58 @@
 	smsm_reset_modem(SMSM_RESET);
 }
 
-int modem_ramdump(int enable, const struct subsys_data *subsys)
+/* FIXME: Get address, size from PIL */
+static struct ramdump_segment modemsw_segments[] = {
+	{0x89000000, 0x8D400000 - 0x89000000},
+};
+
+static struct ramdump_segment modemfw_segments[] = {
+	{0x8D400000, 0x8DA00000 - 0x8D400000},
+};
+
+static struct ramdump_segment smem_segments[] = {
+	{0x80000000, 0x00200000},
+};
+
+static void *modemfw_ramdump_dev;
+static void *modemsw_ramdump_dev;
+static void *smem_ramdump_dev;
+
+static int modem_ramdump(int enable,
+				const struct subsys_data *crashed_subsys)
 {
-	return 0;
+	int ret = 0;
+
+	if (enable) {
+		ret = do_ramdump(modemsw_ramdump_dev, modemsw_segments,
+			ARRAY_SIZE(modemsw_segments));
+
+		if (ret < 0) {
+			pr_err("Unable to dump modem sw memory (rc = %d).\n",
+			       ret);
+			goto out;
+		}
+
+		ret = do_ramdump(modemfw_ramdump_dev, modemfw_segments,
+			ARRAY_SIZE(modemfw_segments));
+
+		if (ret < 0) {
+			pr_err("Unable to dump modem fw memory (rc = %d).\n",
+				ret);
+			goto out;
+		}
+
+		ret = do_ramdump(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 modem_wdog_bite_irq(int irq, void *dev_id)
@@ -263,6 +312,33 @@
 		goto out;
 	}
 
+	modemfw_ramdump_dev = create_ramdump_device("modem_fw");
+
+	if (!modemfw_ramdump_dev) {
+		pr_err("%s: Unable to create modem fw ramdump device. (%d)\n",
+				__func__, -ENOMEM);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	modemsw_ramdump_dev = create_ramdump_device("modem_sw");
+
+	if (!modemsw_ramdump_dev) {
+		pr_err("%s: Unable to create modem sw ramdump device. (%d)\n",
+				__func__, -ENOMEM);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	smem_ramdump_dev = create_ramdump_device("smem");
+
+	if (!smem_ramdump_dev) {
+		pr_err("%s: Unable to create smem ramdump device. (%d)\n",
+				__func__, -ENOMEM);
+		ret = -ENOMEM;
+		goto out;
+	}
+
 	ret = modem_debugfs_init();
 
 	pr_info("%s: modem fatal driver init'ed.\n", __func__);
diff --git a/arch/arm/mach-msm/msm_rq_stats.c b/arch/arm/mach-msm/msm_rq_stats.c
index 9daaaba..da7fb51 100644
--- a/arch/arm/mach-msm/msm_rq_stats.c
+++ b/arch/arm/mach-msm/msm_rq_stats.c
@@ -198,6 +198,8 @@
 
 static int __init msm_rq_stats_init(void)
 {
+	int ret;
+
 	rq_wq = create_singlethread_workqueue("rq_stats");
 	BUG_ON(!rq_wq);
 	INIT_WORK(&rq_info.def_timer_work, def_work_fn);
@@ -206,7 +208,9 @@
 	rq_info.def_timer_jiffies = DEFAULT_DEF_TIMER_JIFFIES;
 	rq_info.rq_poll_last_jiffy = 0;
 	rq_info.def_timer_last_jiffy = 0;
+	ret = init_rq_attribs();
+
 	rq_info.init = 1;
-	return init_rq_attribs();
+	return ret;
 }
 late_initcall(msm_rq_stats_init);
diff --git a/arch/arm/mach-msm/msm_xo.c b/arch/arm/mach-msm/msm_xo.c
index 1e9c05f..29cb1a8 100644
--- a/arch/arm/mach-msm/msm_xo.c
+++ b/arch/arm/mach-msm/msm_xo.c
@@ -223,9 +223,10 @@
 
 	/*
 	 * TODO: Remove early return for 8064 once RPM XO voting support
-	 * is available.
+	 * is available. Remove early return for 8960 TCXO_D0 once all
+	 * voters for it are in place.
 	 */
-	if (cpu_is_apq8064())
+	if (cpu_is_apq8064() || (cpu_is_msm8960() && xo_id == MSM_XO_TCXO_D0))
 		return NULL;
 
 	if (xo_id >= NUM_MSM_XO_IDS) {
diff --git a/arch/arm/mach-msm/peripheral-reset-8960.c b/arch/arm/mach-msm/peripheral-reset-8960.c
index b964417..fa22e4e 100644
--- a/arch/arm/mach-msm/peripheral-reset-8960.c
+++ b/arch/arm/mach-msm/peripheral-reset-8960.c
@@ -28,49 +28,6 @@
 #include "peripheral-loader.h"
 #include "scm-pas.h"
 
-#define MSM_FW_QDSP6SS_PHYS	0x08800000
-#define MSM_SW_QDSP6SS_PHYS	0x08900000
-#define MSM_LPASS_QDSP6SS_PHYS	0x28800000
-#define MSM_MSS_ENABLE_PHYS	0x08B00000
-
-#define QDSP6SS_RST_EVB		0x0
-#define QDSP6SS_RESET		0x04
-#define QDSP6SS_CGC_OVERRIDE	0x18
-#define QDSP6SS_STRAP_TCM	0x1C
-#define QDSP6SS_STRAP_AHB	0x20
-#define QDSP6SS_GFMUX_CTL	0x30
-#define QDSP6SS_PWR_CTL		0x38
-
-#define MSS_S_HCLK_CTL		(MSM_CLK_CTL_BASE + 0x2C70)
-#define MSS_SLP_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2C60)
-#define SFAB_MSS_M_ACLK_CTL	(MSM_CLK_CTL_BASE + 0x2340)
-#define SFAB_MSS_S_HCLK_CTL	(MSM_CLK_CTL_BASE + 0x2C00)
-#define SFAB_MSS_Q6_FW_ACLK_CTL (MSM_CLK_CTL_BASE + 0x2044)
-#define SFAB_MSS_Q6_SW_ACLK_CTL	(MSM_CLK_CTL_BASE + 0x2040)
-#define SFAB_LPASS_Q6_ACLK_CTL	(MSM_CLK_CTL_BASE + 0x23A0)
-#define MSS_Q6FW_JTAG_CLK_CTL	(MSM_CLK_CTL_BASE + 0x2C6C)
-#define MSS_Q6SW_JTAG_CLK_CTL	(MSM_CLK_CTL_BASE + 0x2C68)
-#define MSS_RESET		(MSM_CLK_CTL_BASE + 0x2C64)
-
-#define Q6SS_SS_ARES		BIT(0)
-#define Q6SS_CORE_ARES		BIT(1)
-#define Q6SS_ISDB_ARES		BIT(2)
-#define Q6SS_ETM_ARES		BIT(3)
-#define Q6SS_STOP_CORE_ARES	BIT(4)
-#define Q6SS_PRIV_ARES		BIT(5)
-
-#define Q6SS_L2DATA_SLP_NRET_N	BIT(0)
-#define Q6SS_SLP_RET_N		BIT(1)
-#define Q6SS_L1TCM_SLP_NRET_N	BIT(2)
-#define Q6SS_L2TAG_SLP_NRET_N	BIT(3)
-#define Q6SS_ETB_SLEEP_NRET_N	BIT(4)
-#define Q6SS_ARR_STBY_N		BIT(5)
-#define Q6SS_CLAMP_IO		BIT(6)
-
-#define Q6SS_CLK_ENA		BIT(1)
-#define Q6SS_SRC_SWITCH_CLK_OVR	BIT(8)
-#define Q6SS_AXIS_ACLK_EN	BIT(9)
-
 #define MSM_RIVA_PHYS			0x03204000
 #define RIVA_PMU_A2XB_CFG		(msm_riva_base + 0xB8)
 #define RIVA_PMU_A2XB_CFG_EN		BIT(0)
@@ -121,339 +78,14 @@
 #define PPSS_PROC_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2588)
 #define PPSS_HCLK_CTL			(MSM_CLK_CTL_BASE + 0x2580)
 
-struct q6_data {
-	const unsigned strap_tcm_base;
-	const unsigned strap_ahb_upper;
-	const unsigned strap_ahb_lower;
-	const unsigned reg_base_phys;
-	void __iomem *reg_base;
-	void __iomem *aclk_reg;
-	void __iomem *jtag_clk_reg;
-	int start_addr;
-	struct regulator *vreg;
-	bool vreg_enabled;
-	const char *name;
-};
-
-static struct q6_data q6_lpass = {
-	.strap_tcm_base  = (0x146 << 16),
-	.strap_ahb_upper = (0x029 << 16),
-	.strap_ahb_lower = (0x028 << 4),
-	.reg_base_phys = MSM_LPASS_QDSP6SS_PHYS,
-	.aclk_reg = SFAB_LPASS_Q6_ACLK_CTL,
-	.name = "q6_lpass",
-};
-
-static struct q6_data q6_modem_fw = {
-	.strap_tcm_base  = (0x40 << 16),
-	.strap_ahb_upper = (0x09 << 16),
-	.strap_ahb_lower = (0x08 << 4),
-	.reg_base_phys = MSM_FW_QDSP6SS_PHYS,
-	.aclk_reg = SFAB_MSS_Q6_FW_ACLK_CTL,
-	.jtag_clk_reg = MSS_Q6FW_JTAG_CLK_CTL,
-	.name = "q6_modem_fw",
-};
-
-static struct q6_data q6_modem_sw = {
-	.strap_tcm_base  = (0x42 << 16),
-	.strap_ahb_upper = (0x09 << 16),
-	.strap_ahb_lower = (0x08 << 4),
-	.reg_base_phys = MSM_SW_QDSP6SS_PHYS,
-	.aclk_reg = SFAB_MSS_Q6_SW_ACLK_CTL,
-	.jtag_clk_reg = MSS_Q6SW_JTAG_CLK_CTL,
-	.name = "q6_modem_sw",
-};
-
-static void __iomem *mss_enable_reg;
 static void __iomem *msm_riva_base;
 static unsigned long riva_start;
 
-static int init_image_lpass_q6_trusted(struct pil_desc *pil,
-				       const u8 *metadata, size_t size)
-{
-	return pas_init_image(PAS_Q6, metadata, size);
-}
-
-static int init_image_modem_fw_q6_trusted(struct pil_desc *pil,
-					  const u8 *metadata, size_t size)
-{
-	return pas_init_image(PAS_MODEM_FW, metadata, size);
-}
-
-static int init_image_modem_sw_q6_trusted(struct pil_desc *pil,
-					  const u8 *metadata, size_t size)
-{
-	return pas_init_image(PAS_MODEM_SW, metadata, size);
-}
-
-static int init_image_lpass_q6_untrusted(struct pil_desc *pil,
-					 const u8 *metadata, size_t size)
-{
-	const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
-	q6_lpass.start_addr = ehdr->e_entry;
-	return 0;
-}
-
-static int init_image_modem_fw_q6_untrusted(struct pil_desc *pil,
-					    const u8 *metadata, size_t size)
-{
-	const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
-	q6_modem_fw.start_addr = ehdr->e_entry;
-	return 0;
-}
-
-static int init_image_modem_sw_q6_untrusted(struct pil_desc *pil,
-					    const u8 *metadata, size_t size)
-{
-	const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
-	q6_modem_sw.start_addr = ehdr->e_entry;
-	return 0;
-}
-
 static int verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
 {
 	return 0;
 }
 
-static int power_up_q6(struct q6_data *q6)
-{
-	int err;
-
-	err = regulator_set_voltage(q6->vreg, 1050000, 1050000);
-	if (err) {
-		pr_err("Failed to set %s regulator's voltage.\n", q6->name);
-		return err;
-	}
-	err = regulator_set_optimum_mode(q6->vreg, 100000);
-	if (err < 0) {
-		pr_err("Failed to set %s regulator's mode.\n", q6->name);
-		return err;
-	}
-	err = regulator_enable(q6->vreg);
-	if (err) {
-		pr_err("Failed to enable %s's regulator.\n", q6->name);
-		return err;
-	}
-	q6->vreg_enabled = true;
-	return 0;
-}
-
-static int reset_q6_trusted(int id, struct q6_data *q6)
-{
-	int err = power_up_q6(q6);
-	if (err)
-		return err;
-	return pas_auth_and_reset(id);
-}
-
-static int reset_lpass_q6_trusted(struct pil_desc *pil)
-{
-	return reset_q6_trusted(PAS_Q6, &q6_lpass);
-}
-
-static int reset_modem_fw_q6_trusted(struct pil_desc *pil)
-{
-	return reset_q6_trusted(PAS_MODEM_FW, &q6_modem_fw);
-}
-
-static int reset_modem_sw_q6_trusted(struct pil_desc *pil)
-{
-	return reset_q6_trusted(PAS_MODEM_SW, &q6_modem_sw);
-}
-
-static int reset_q6_untrusted(struct q6_data *q6)
-{
-	u32 reg, err = 0;
-
-	err = power_up_q6(q6);
-	if (err)
-		return err;
-	/* Enable Q6 ACLK */
-	writel_relaxed(0x10, q6->aclk_reg);
-
-	if (q6 == &q6_modem_fw || q6 == &q6_modem_sw) {
-		/* Enable MSS clocks */
-		writel_relaxed(0x10, SFAB_MSS_M_ACLK_CTL);
-		writel_relaxed(0x10, SFAB_MSS_S_HCLK_CTL);
-		writel_relaxed(0x10, MSS_S_HCLK_CTL);
-		writel_relaxed(0x10, MSS_SLP_CLK_CTL);
-		/* Wait for clocks to enable */
-		mb();
-		udelay(10);
-
-		/* Enable JTAG clocks */
-		/* TODO: Remove if/when Q6 software enables them? */
-		writel_relaxed(0x10, q6->jtag_clk_reg);
-
-		/* De-assert MSS reset */
-		writel_relaxed(0x0,  MSS_RESET);
-		mb();
-		udelay(10);
-
-		/* Enable MSS */
-		writel_relaxed(0x7,  mss_enable_reg);
-	}
-
-	/*
-	 * Assert AXIS_ACLK_EN override to allow for correct updating of the
-	 * QDSP6_CORE_STATE status bit. This is mandatory only for the SW Q6
-	 * in 8960v1 and optional elsewhere.
-	 */
-	reg = readl_relaxed(q6->reg_base + QDSP6SS_CGC_OVERRIDE);
-	reg |= Q6SS_AXIS_ACLK_EN;
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_CGC_OVERRIDE);
-
-	/* Deassert Q6SS_SS_ARES */
-	reg = readl_relaxed(q6->reg_base + QDSP6SS_RESET);
-	reg &= ~(Q6SS_SS_ARES);
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_RESET);
-
-	/* Program boot address */
-	writel_relaxed((q6->start_addr >> 8) & 0xFFFFFF,
-			q6->reg_base + QDSP6SS_RST_EVB);
-
-	/* Program TCM and AHB address ranges */
-	writel_relaxed(q6->strap_tcm_base, q6->reg_base + QDSP6SS_STRAP_TCM);
-	writel_relaxed(q6->strap_ahb_upper | q6->strap_ahb_lower,
-		       q6->reg_base + QDSP6SS_STRAP_AHB);
-
-	/* Turn off Q6 core clock */
-	writel_relaxed(Q6SS_SRC_SWITCH_CLK_OVR,
-		       q6->reg_base + QDSP6SS_GFMUX_CTL);
-
-	/* Put memories to sleep */
-	writel_relaxed(Q6SS_CLAMP_IO, q6->reg_base + QDSP6SS_PWR_CTL);
-
-	/* Assert resets */
-	reg = readl_relaxed(q6->reg_base + QDSP6SS_RESET);
-	reg |= (Q6SS_CORE_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES
-	    | Q6SS_STOP_CORE_ARES);
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_RESET);
-
-	/* Wait 8 AHB cycles for Q6 to be fully reset (AHB = 1.5Mhz) */
-	mb();
-	usleep_range(20, 30);
-
-	/* Turn on Q6 memories */
-	reg = Q6SS_L2DATA_SLP_NRET_N | Q6SS_SLP_RET_N | Q6SS_L1TCM_SLP_NRET_N
-	    | Q6SS_L2TAG_SLP_NRET_N | Q6SS_ETB_SLEEP_NRET_N | Q6SS_ARR_STBY_N
-	    | Q6SS_CLAMP_IO;
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_PWR_CTL);
-
-	/* Turn on Q6 core clock */
-	reg = Q6SS_CLK_ENA | Q6SS_SRC_SWITCH_CLK_OVR;
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_GFMUX_CTL);
-
-	/* Remove Q6SS_CLAMP_IO */
-	reg = readl_relaxed(q6->reg_base + QDSP6SS_PWR_CTL);
-	reg &= ~Q6SS_CLAMP_IO;
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_PWR_CTL);
-
-	/* Bring Q6 core out of reset and start execution. */
-	writel_relaxed(0x0, q6->reg_base + QDSP6SS_RESET);
-
-	/*
-	 * Re-enable auto-gating of AXIS_ACLK at lease one AXI clock cycle
-	 * after resets are de-asserted.
-	 */
-	mb();
-	usleep_range(1, 10);
-	reg = readl_relaxed(q6->reg_base + QDSP6SS_CGC_OVERRIDE);
-	reg &= ~Q6SS_AXIS_ACLK_EN;
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_CGC_OVERRIDE);
-
-	return 0;
-}
-
-static int reset_lpass_q6_untrusted(struct pil_desc *pil)
-{
-	return reset_q6_untrusted(&q6_lpass);
-}
-
-static int reset_modem_fw_q6_untrusted(struct pil_desc *pil)
-{
-	return reset_q6_untrusted(&q6_modem_fw);
-}
-
-static int reset_modem_sw_q6_untrusted(struct pil_desc *pil)
-{
-	return reset_q6_untrusted(&q6_modem_sw);
-}
-
-static int shutdown_q6_trusted(int id, struct q6_data *q6)
-{
-	int ret;
-
-	ret = pas_shutdown(id);
-	if (ret)
-		return ret;
-
-	if (q6->vreg_enabled) {
-		regulator_disable(q6->vreg);
-		q6->vreg_enabled = false;
-	}
-
-	return ret;
-}
-
-static int shutdown_lpass_q6_trusted(struct pil_desc *pil)
-{
-	return shutdown_q6_trusted(PAS_Q6, &q6_lpass);
-}
-
-static int shutdown_modem_fw_q6_trusted(struct pil_desc *pil)
-{
-	return shutdown_q6_trusted(PAS_MODEM_FW, &q6_modem_fw);
-}
-
-static int shutdown_modem_sw_q6_trusted(struct pil_desc *pil)
-{
-	return shutdown_q6_trusted(PAS_MODEM_SW, &q6_modem_sw);
-}
-
-static int shutdown_q6_untrusted(struct q6_data *q6)
-{
-	u32 reg;
-
-	/* Turn off Q6 core clock */
-	writel_relaxed(Q6SS_SRC_SWITCH_CLK_OVR,
-		       q6->reg_base + QDSP6SS_GFMUX_CTL);
-
-	/* Assert resets */
-	reg = (Q6SS_SS_ARES | Q6SS_CORE_ARES | Q6SS_ISDB_ARES
-	     | Q6SS_ETM_ARES | Q6SS_STOP_CORE_ARES | Q6SS_PRIV_ARES);
-	writel_relaxed(reg, q6->reg_base + QDSP6SS_RESET);
-
-	/* Turn off Q6 memories */
-	writel_relaxed(Q6SS_CLAMP_IO, q6->reg_base + QDSP6SS_PWR_CTL);
-
-	/* Put Modem Subsystem back into reset when shutting down FWQ6 */
-	if (q6 == &q6_modem_fw)
-		writel_relaxed(0x1, MSS_RESET);
-
-	if (q6->vreg_enabled) {
-		regulator_disable(q6->vreg);
-		q6->vreg_enabled = false;
-	}
-
-	return 0;
-}
-
-static int shutdown_lpass_q6_untrusted(struct pil_desc *pil)
-{
-	return shutdown_q6_untrusted(&q6_lpass);
-}
-
-static int shutdown_modem_fw_q6_untrusted(struct pil_desc *pil)
-{
-	return shutdown_q6_untrusted(&q6_modem_fw);
-}
-
-static int shutdown_modem_sw_q6_untrusted(struct pil_desc *pil)
-{
-	return shutdown_q6_untrusted(&q6_modem_sw);
-}
-
 static int init_image_riva_untrusted(struct pil_desc *pil, const u8 *metadata,
 				     size_t size)
 {
@@ -468,49 +100,55 @@
 	bool xo;
 
 	/* Enable A2XB bridge */
-	reg = readl(RIVA_PMU_A2XB_CFG);
+	reg = readl_relaxed(RIVA_PMU_A2XB_CFG);
 	reg |= RIVA_PMU_A2XB_CFG_EN;
-	writel(reg, RIVA_PMU_A2XB_CFG);
+	writel_relaxed(reg, RIVA_PMU_A2XB_CFG);
 
 	/* Determine which XO to use */
-	reg = readl(RIVA_PMU_CFG);
+	reg = readl_relaxed(RIVA_PMU_CFG);
 	xo = (reg & RIVA_PMU_CFG_IRIS_XO_MODE) == RIVA_PMU_CFG_IRIS_XO_MODE_48;
 
 	/* Program PLL 13 to 960 MHz */
-	reg = readl(RIVA_PLL_MODE);
+	reg = readl_relaxed(RIVA_PLL_MODE);
 	reg &= ~(PLL_MODE_BYPASSNL | PLL_MODE_OUTCTRL | PLL_MODE_RESET_N);
-	writel(reg, RIVA_PLL_MODE);
+	writel_relaxed(reg, RIVA_PLL_MODE);
 
 	if (xo)
-		writel(0x40000C00 | 40, RIVA_PLL_L_VAL);
+		writel_relaxed(0x40000C00 | 40, RIVA_PLL_L_VAL);
 	else
-		writel(0x40000C00 | 50, RIVA_PLL_L_VAL);
-	writel(0, RIVA_PLL_M_VAL);
-	writel(1, RIVA_PLL_N_VAL);
+		writel_relaxed(0x40000C00 | 50, RIVA_PLL_L_VAL);
+	writel_relaxed(0, RIVA_PLL_M_VAL);
+	writel_relaxed(1, RIVA_PLL_N_VAL);
 	writel_relaxed(0x01495227, RIVA_PLL_CONFIG);
 
-	reg = readl(RIVA_PLL_MODE);
+	reg = readl_relaxed(RIVA_PLL_MODE);
 	reg &= ~(PLL_MODE_REF_XO_SEL);
 	reg |= xo ? PLL_MODE_REF_XO_SEL_RF : PLL_MODE_REF_XO_SEL_CXO;
-	writel(reg, RIVA_PLL_MODE);
+	writel_relaxed(reg, RIVA_PLL_MODE);
 
 	/* Enable PLL 13 */
 	reg |= PLL_MODE_BYPASSNL;
-	writel(reg, RIVA_PLL_MODE);
+	writel_relaxed(reg, RIVA_PLL_MODE);
 
+	/*
+	 * H/W requires a 5us delay between disabling the bypass and
+	 * de-asserting the reset. Delay 10us just to be safe.
+	 */
+	mb();
 	usleep_range(10, 20);
 
 	reg |= PLL_MODE_RESET_N;
-	writel(reg, RIVA_PLL_MODE);
+	writel_relaxed(reg, RIVA_PLL_MODE);
 	reg |= PLL_MODE_OUTCTRL;
-	writel(reg, RIVA_PLL_MODE);
+	writel_relaxed(reg, RIVA_PLL_MODE);
 
 	/* Wait for PLL to settle */
+	mb();
 	usleep_range(50, 100);
 
 	/* Configure cCPU for 240 MHz */
-	reg = readl(RIVA_PMU_CLK_ROOT3);
-	if (readl(RIVA_PMU_ROOT_CLK_SEL) & RIVA_PMU_ROOT_CLK_SEL_3) {
+	reg = readl_relaxed(RIVA_PMU_CLK_ROOT3);
+	if (readl_relaxed(RIVA_PMU_ROOT_CLK_SEL) & RIVA_PMU_ROOT_CLK_SEL_3) {
 		reg &= ~(RIVA_PMU_CLK_ROOT3_SRC0_SEL |
 			 RIVA_PMU_CLK_ROOT3_SRC0_DIV);
 		reg |= RIVA_PMU_CLK_ROOT3_SRC0_SEL_RIVA |
@@ -521,34 +159,34 @@
 		reg |= RIVA_PMU_CLK_ROOT3_SRC1_SEL_RIVA |
 		       RIVA_PMU_CLK_ROOT3_SRC1_DIV_2;
 	}
-	writel(reg, RIVA_PMU_CLK_ROOT3);
+	writel_relaxed(reg, RIVA_PMU_CLK_ROOT3);
 	reg |= RIVA_PMU_CLK_ROOT3_ENA;
-	writel(reg, RIVA_PMU_CLK_ROOT3);
-	reg = readl(RIVA_PMU_ROOT_CLK_SEL);
+	writel_relaxed(reg, RIVA_PMU_CLK_ROOT3);
+	reg = readl_relaxed(RIVA_PMU_ROOT_CLK_SEL);
 	reg ^= RIVA_PMU_ROOT_CLK_SEL_3;
-	writel(reg, RIVA_PMU_ROOT_CLK_SEL);
+	writel_relaxed(reg, RIVA_PMU_ROOT_CLK_SEL);
 
 	/* Use the high vector table */
-	reg = readl(RIVA_PMU_CCPU_CTL);
+	reg = readl_relaxed(RIVA_PMU_CCPU_CTL);
 	reg |= RIVA_PMU_CCPU_CTL_HIGH_IVT | RIVA_PMU_CCPU_CTL_REMAP_EN;
-	writel(reg, RIVA_PMU_CCPU_CTL);
+	writel_relaxed(reg, RIVA_PMU_CCPU_CTL);
 
 	/* Set base memory address */
 	writel_relaxed(riva_start >> 16, RIVA_PMU_CCPU_BOOT_REMAP_ADDR);
 
 	/* Clear warmboot bit indicating this is a cold boot */
-	reg = readl(RIVA_PMU_CFG);
+	reg = readl_relaxed(RIVA_PMU_CFG);
 	reg &= ~(RIVA_PMU_CFG_WARM_BOOT);
-	writel(reg, RIVA_PMU_CFG);
+	writel_relaxed(reg, RIVA_PMU_CFG);
 
 	/* Enable the cCPU clock */
-	reg = readl(RIVA_PMU_OVRD_VAL);
+	reg = readl_relaxed(RIVA_PMU_OVRD_VAL);
 	reg |= RIVA_PMU_OVRD_VAL_CCPU_CLK;
-	writel(reg, RIVA_PMU_OVRD_VAL);
+	writel_relaxed(reg, RIVA_PMU_OVRD_VAL);
 
 	/* Take cCPU out of reset */
 	reg |= RIVA_PMU_OVRD_VAL_CCPU_RESET;
-	writel(reg, RIVA_PMU_OVRD_VAL);
+	writel_relaxed(reg, RIVA_PMU_OVRD_VAL);
 
 	return 0;
 }
@@ -557,9 +195,9 @@
 {
 	u32 reg;
 	/* Put riva into reset */
-	reg = readl(RIVA_PMU_OVRD_VAL);
+	reg = readl_relaxed(RIVA_PMU_OVRD_VAL);
 	reg &= ~(RIVA_PMU_OVRD_VAL_CCPU_RESET | RIVA_PMU_OVRD_VAL_CCPU_CLK);
-	writel(reg, RIVA_PMU_OVRD_VAL);
+	writel_relaxed(reg, RIVA_PMU_OVRD_VAL);
 	return 0;
 }
 
@@ -635,27 +273,6 @@
 	return pas_shutdown(PAS_TZAPPS);
 }
 
-static struct pil_reset_ops pil_modem_fw_q6_ops = {
-	.init_image = init_image_modem_fw_q6_untrusted,
-	.verify_blob = verify_blob,
-	.auth_and_reset = reset_modem_fw_q6_untrusted,
-	.shutdown = shutdown_modem_fw_q6_untrusted,
-};
-
-static struct pil_reset_ops pil_modem_sw_q6_ops = {
-	.init_image = init_image_modem_sw_q6_untrusted,
-	.verify_blob = verify_blob,
-	.auth_and_reset = reset_modem_sw_q6_untrusted,
-	.shutdown = shutdown_modem_sw_q6_untrusted,
-};
-
-static struct pil_reset_ops pil_lpass_q6_ops = {
-	.init_image = init_image_lpass_q6_untrusted,
-	.verify_blob = verify_blob,
-	.auth_and_reset = reset_lpass_q6_untrusted,
-	.shutdown = shutdown_lpass_q6_untrusted,
-};
-
 static struct pil_reset_ops pil_riva_ops = {
 	.init_image = init_image_riva_untrusted,
 	.verify_blob = verify_blob,
@@ -677,38 +294,6 @@
 	.shutdown = shutdown_tzapps,
 };
 
-static struct platform_device pil_lpass_q6 = {
-	.name = "pil_lpass_q6",
-};
-
-static struct pil_desc pil_lpass_q6_desc = {
-	.name = "q6",
-	.dev = &pil_lpass_q6.dev,
-	.ops = &pil_lpass_q6_ops,
-};
-
-static struct platform_device pil_modem_fw_q6 = {
-	.name = "pil_modem_fw_q6",
-};
-
-static struct pil_desc pil_modem_fw_q6_desc = {
-	.name = "modem_fw",
-	.depends_on = "q6",
-	.dev = &pil_modem_fw_q6.dev,
-	.ops = &pil_modem_fw_q6_ops,
-};
-
-static struct platform_device pil_modem_sw_q6 = {
-	.name = "pil_modem_sw_q6",
-};
-
-static struct pil_desc pil_modem_sw_q6_desc = {
-	.name = "modem",
-	.depends_on = "modem_fw",
-	.dev = &pil_modem_sw_q6.dev,
-	.ops = &pil_modem_sw_q6_ops,
-};
-
 static struct platform_device pil_riva = {
 	.name = "pil_riva",
 };
@@ -739,51 +324,8 @@
 	.ops = &pil_tzapps_ops,
 };
 
-static int __init q6_reset_init(struct q6_data *q6)
-{
-	int err;
-
-	q6->reg_base = ioremap(q6->reg_base_phys, SZ_256);
-	if (!q6->reg_base) {
-		err = -ENOMEM;
-		goto err_map;
-	}
-
-	q6->vreg = regulator_get(NULL, q6->name);
-	if (IS_ERR(q6->vreg)) {
-		err = PTR_ERR(q6->vreg);
-		goto err_vreg;
-	}
-
-	return 0;
-
-err_vreg:
-	iounmap(q6->reg_base);
-err_map:
-	return err;
-}
-
 static void __init use_secure_pil(void)
 {
-
-	if (pas_supported(PAS_Q6) > 0) {
-		pil_lpass_q6_ops.init_image = init_image_lpass_q6_trusted;
-		pil_lpass_q6_ops.auth_and_reset = reset_lpass_q6_trusted;
-		pil_lpass_q6_ops.shutdown = shutdown_lpass_q6_trusted;
-	}
-
-	if (pas_supported(PAS_MODEM_FW) > 0) {
-		pil_modem_fw_q6_ops.init_image = init_image_modem_fw_q6_trusted;
-		pil_modem_fw_q6_ops.auth_and_reset = reset_modem_fw_q6_trusted;
-		pil_modem_fw_q6_ops.shutdown = shutdown_modem_fw_q6_trusted;
-	}
-
-	if (pas_supported(PAS_MODEM_SW) > 0) {
-		pil_modem_sw_q6_ops.init_image = init_image_modem_sw_q6_trusted;
-		pil_modem_sw_q6_ops.auth_and_reset = reset_modem_sw_q6_trusted;
-		pil_modem_sw_q6_ops.shutdown = shutdown_modem_sw_q6_trusted;
-	}
-
 	if (pas_supported(PAS_DSPS) > 0) {
 		pil_dsps_ops.init_image = init_image_dsps_trusted;
 		pil_dsps_ops.auth_and_reset = reset_dsps_trusted;
@@ -797,11 +339,8 @@
 	}
 }
 
-
 static int __init msm_peripheral_reset_init(void)
 {
-	int err;
-
 	/*
 	 * Don't initialize PIL on simulated targets, as some
 	 * subsystems may not be emulated on them.
@@ -811,34 +350,6 @@
 
 	use_secure_pil();
 
-	err = q6_reset_init(&q6_lpass);
-	if (err)
-		return err;
-	BUG_ON(platform_device_register(&pil_lpass_q6));
-	BUG_ON(msm_pil_register(&pil_lpass_q6_desc));
-
-	mss_enable_reg = ioremap(MSM_MSS_ENABLE_PHYS, 4);
-	if (!mss_enable_reg)
-		return -ENOMEM;
-
-	err = q6_reset_init(&q6_modem_fw);
-	if (err) {
-		iounmap(mss_enable_reg);
-		return err;
-	}
-	BUG_ON(platform_device_register(&pil_modem_fw_q6));
-	if (err) {
-		iounmap(mss_enable_reg);
-		return err;
-	}
-	BUG_ON(msm_pil_register(&pil_modem_fw_q6_desc));
-
-	err = q6_reset_init(&q6_modem_sw);
-	if (err)
-		return err;
-	BUG_ON(platform_device_register(&pil_modem_sw_q6));
-	BUG_ON(msm_pil_register(&pil_modem_sw_q6_desc));
-
 	BUG_ON(platform_device_register(&pil_dsps));
 	BUG_ON(msm_pil_register(&pil_dsps_desc));
 	BUG_ON(platform_device_register(&pil_tzapps));
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
new file mode 100644
index 0000000..24c479c
--- /dev/null
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -0,0 +1,460 @@
+/* Copyright (c) 2011, 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/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/regulator/consumer.h>
+#include <linux/elf.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include <mach/msm_bus.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_xo.h>
+
+#include "peripheral-loader.h"
+#include "pil-q6v4.h"
+#include "scm-pas.h"
+
+#define PROXY_VOTE_TIMEOUT	10000
+
+#define QDSP6SS_RST_EVB		0x0
+#define QDSP6SS_RESET		0x04
+#define QDSP6SS_CGC_OVERRIDE	0x18
+#define QDSP6SS_STRAP_TCM	0x1C
+#define QDSP6SS_STRAP_AHB	0x20
+#define QDSP6SS_GFMUX_CTL	0x30
+#define QDSP6SS_PWR_CTL		0x38
+
+#define MSS_S_HCLK_CTL		(MSM_CLK_CTL_BASE + 0x2C70)
+#define MSS_SLP_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2C60)
+#define SFAB_MSS_M_ACLK_CTL	(MSM_CLK_CTL_BASE + 0x2340)
+#define SFAB_MSS_S_HCLK_CTL	(MSM_CLK_CTL_BASE + 0x2C00)
+#define MSS_RESET		(MSM_CLK_CTL_BASE + 0x2C64)
+
+#define Q6SS_SS_ARES		BIT(0)
+#define Q6SS_CORE_ARES		BIT(1)
+#define Q6SS_ISDB_ARES		BIT(2)
+#define Q6SS_ETM_ARES		BIT(3)
+#define Q6SS_STOP_CORE_ARES	BIT(4)
+#define Q6SS_PRIV_ARES		BIT(5)
+
+#define Q6SS_L2DATA_SLP_NRET_N	BIT(0)
+#define Q6SS_SLP_RET_N		BIT(1)
+#define Q6SS_L1TCM_SLP_NRET_N	BIT(2)
+#define Q6SS_L2TAG_SLP_NRET_N	BIT(3)
+#define Q6SS_ETB_SLEEP_NRET_N	BIT(4)
+#define Q6SS_ARR_STBY_N		BIT(5)
+#define Q6SS_CLAMP_IO		BIT(6)
+
+#define Q6SS_CLK_ENA		BIT(1)
+#define Q6SS_SRC_SWITCH_CLK_OVR	BIT(8)
+#define Q6SS_AXIS_ACLK_EN	BIT(9)
+
+struct q6v4_data {
+	void __iomem *base;
+	void __iomem *modem_base;
+	unsigned long start_addr;
+	struct regulator *vreg;
+	bool vreg_enabled;
+	struct msm_xo_voter *xo;
+	struct timer_list xo_timer;
+};
+
+static int pil_q6v4_init_image(struct pil_desc *pil, const u8 *metadata,
+		size_t size)
+{
+	const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
+	struct q6v4_data *drv = dev_get_drvdata(pil->dev);
+	drv->start_addr = ehdr->e_entry;
+	return 0;
+}
+
+static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
+{
+	return 0;
+}
+
+static void pil_q6v4_make_xo_proxy_votes(struct device *dev)
+{
+	struct q6v4_data *drv = dev_get_drvdata(dev);
+
+	msm_xo_mode_vote(drv->xo, MSM_XO_MODE_ON);
+	mod_timer(&drv->xo_timer, jiffies+msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+}
+
+static void pil_q6v4_remove_xo_proxy_votes(unsigned long data)
+{
+	struct q6v4_data *drv = (struct q6v4_data *)data;
+
+	msm_xo_mode_vote(drv->xo, MSM_XO_MODE_OFF);
+}
+
+static void pil_q6v4_remove_xo_proxy_votes_now(struct device *dev)
+{
+	struct q6v4_data *drv = dev_get_drvdata(dev);
+
+	if (del_timer(&drv->xo_timer))
+		pil_q6v4_remove_xo_proxy_votes((unsigned long)drv);
+}
+
+static int pil_q6v4_power_up(struct device *dev)
+{
+	int err;
+	struct q6v4_data *drv = dev_get_drvdata(dev);
+
+	err = regulator_set_voltage(drv->vreg, 1050000, 1050000);
+	if (err) {
+		dev_err(dev, "Failed to set regulator's voltage.\n");
+		return err;
+	}
+	err = regulator_set_optimum_mode(drv->vreg, 100000);
+	if (err < 0) {
+		dev_err(dev, "Failed to set regulator's mode.\n");
+		return err;
+	}
+	err = regulator_enable(drv->vreg);
+	if (err) {
+		dev_err(dev, "Failed to enable regulator.\n");
+		return err;
+	}
+	drv->vreg_enabled = true;
+	return 0;
+}
+
+static DEFINE_MUTEX(pil_q6v4_modem_lock);
+static unsigned pil_q6v4_modem_count;
+
+/* Bring modem subsystem out of reset */
+static void pil_q6v4_init_modem(void __iomem *base, void __iomem *jtag_clk)
+{
+	mutex_lock(&pil_q6v4_modem_lock);
+	if (!pil_q6v4_modem_count) {
+		/* Enable MSS clocks */
+		writel_relaxed(0x10, SFAB_MSS_M_ACLK_CTL);
+		writel_relaxed(0x10, SFAB_MSS_S_HCLK_CTL);
+		writel_relaxed(0x10, MSS_S_HCLK_CTL);
+		writel_relaxed(0x10, MSS_SLP_CLK_CTL);
+		/* Wait for clocks to enable */
+		mb();
+		udelay(10);
+
+		/* De-assert MSS reset */
+		writel_relaxed(0x0, MSS_RESET);
+		mb();
+		udelay(10);
+		/* Enable MSS */
+		writel_relaxed(0x7, base);
+	}
+
+	/* Enable JTAG clocks */
+	/* TODO: Remove if/when Q6 software enables them? */
+	writel_relaxed(0x10, jtag_clk);
+
+	pil_q6v4_modem_count++;
+	mutex_unlock(&pil_q6v4_modem_lock);
+}
+
+/* Put modem subsystem back into reset */
+static void pil_q6v4_shutdown_modem(void)
+{
+	mutex_lock(&pil_q6v4_modem_lock);
+	if (pil_q6v4_modem_count)
+		pil_q6v4_modem_count--;
+	if (pil_q6v4_modem_count == 0)
+		writel_relaxed(0x1, MSS_RESET);
+	mutex_unlock(&pil_q6v4_modem_lock);
+}
+
+static int pil_q6v4_reset(struct pil_desc *pil)
+{
+	u32 reg, err = 0;
+	const struct q6v4_data *drv = dev_get_drvdata(pil->dev);
+	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
+
+	pil_q6v4_make_xo_proxy_votes(pil->dev);
+
+	err = pil_q6v4_power_up(pil->dev);
+	if (err)
+		return err;
+	/* Enable Q6 ACLK */
+	writel_relaxed(0x10, pdata->aclk_reg);
+
+	if (drv->modem_base)
+		pil_q6v4_init_modem(drv->modem_base, pdata->jtag_clk_reg);
+
+	/* Unhalt bus port */
+	err = msm_bus_axi_portunhalt(pdata->bus_port);
+	if (err)
+		dev_err(pil->dev, "Failed to unhalt bus port\n");
+
+	/*
+	 * Assert AXIS_ACLK_EN override to allow for correct updating of the
+	 * QDSP6_CORE_STATE status bit. This is mandatory only for the SW Q6
+	 * in 8960v1 and optional elsewhere.
+	 */
+	reg = readl_relaxed(drv->base + QDSP6SS_CGC_OVERRIDE);
+	reg |= Q6SS_AXIS_ACLK_EN;
+	writel_relaxed(reg, drv->base + QDSP6SS_CGC_OVERRIDE);
+
+	/* Deassert Q6SS_SS_ARES */
+	reg = readl_relaxed(drv->base + QDSP6SS_RESET);
+	reg &= ~(Q6SS_SS_ARES);
+	writel_relaxed(reg, drv->base + QDSP6SS_RESET);
+
+	/* Program boot address */
+	writel_relaxed((drv->start_addr >> 8) & 0xFFFFFF,
+			drv->base + QDSP6SS_RST_EVB);
+
+	/* Program TCM and AHB address ranges */
+	writel_relaxed(pdata->strap_tcm_base, drv->base + QDSP6SS_STRAP_TCM);
+	writel_relaxed(pdata->strap_ahb_upper | pdata->strap_ahb_lower,
+		       drv->base + QDSP6SS_STRAP_AHB);
+
+	/* Turn off Q6 core clock */
+	writel_relaxed(Q6SS_SRC_SWITCH_CLK_OVR,
+		       drv->base + QDSP6SS_GFMUX_CTL);
+
+	/* Put memories to sleep */
+	writel_relaxed(Q6SS_CLAMP_IO, drv->base + QDSP6SS_PWR_CTL);
+
+	/* Assert resets */
+	reg = readl_relaxed(drv->base + QDSP6SS_RESET);
+	reg |= (Q6SS_CORE_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES
+	    | Q6SS_STOP_CORE_ARES);
+	writel_relaxed(reg, drv->base + QDSP6SS_RESET);
+
+	/* Wait 8 AHB cycles for Q6 to be fully reset (AHB = 1.5Mhz) */
+	mb();
+	usleep_range(20, 30);
+
+	/* Turn on Q6 memories */
+	reg = Q6SS_L2DATA_SLP_NRET_N | Q6SS_SLP_RET_N | Q6SS_L1TCM_SLP_NRET_N
+	    | Q6SS_L2TAG_SLP_NRET_N | Q6SS_ETB_SLEEP_NRET_N | Q6SS_ARR_STBY_N
+	    | Q6SS_CLAMP_IO;
+	writel_relaxed(reg, drv->base + QDSP6SS_PWR_CTL);
+
+	/* Turn on Q6 core clock */
+	reg = Q6SS_CLK_ENA | Q6SS_SRC_SWITCH_CLK_OVR;
+	writel_relaxed(reg, drv->base + QDSP6SS_GFMUX_CTL);
+
+	/* Remove Q6SS_CLAMP_IO */
+	reg = readl_relaxed(drv->base + QDSP6SS_PWR_CTL);
+	reg &= ~Q6SS_CLAMP_IO;
+	writel_relaxed(reg, drv->base + QDSP6SS_PWR_CTL);
+
+	/* Bring Q6 core out of reset and start execution. */
+	writel_relaxed(0x0, drv->base + QDSP6SS_RESET);
+
+	/*
+	 * Re-enable auto-gating of AXIS_ACLK at lease one AXI clock cycle
+	 * after resets are de-asserted.
+	 */
+	mb();
+	usleep_range(1, 10);
+	reg = readl_relaxed(drv->base + QDSP6SS_CGC_OVERRIDE);
+	reg &= ~Q6SS_AXIS_ACLK_EN;
+	writel_relaxed(reg, drv->base + QDSP6SS_CGC_OVERRIDE);
+
+	return 0;
+}
+
+static int pil_q6v4_shutdown(struct pil_desc *pil)
+{
+	u32 reg;
+	struct q6v4_data *drv = dev_get_drvdata(pil->dev);
+	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
+
+	/* Make sure bus port is halted */
+	msm_bus_axi_porthalt(pdata->bus_port);
+
+	/* Turn off Q6 core clock */
+	writel_relaxed(Q6SS_SRC_SWITCH_CLK_OVR,
+		       drv->base + QDSP6SS_GFMUX_CTL);
+
+	/* Assert resets */
+	reg = (Q6SS_SS_ARES | Q6SS_CORE_ARES | Q6SS_ISDB_ARES
+	     | Q6SS_ETM_ARES | Q6SS_STOP_CORE_ARES | Q6SS_PRIV_ARES);
+	writel_relaxed(reg, drv->base + QDSP6SS_RESET);
+
+	/* Turn off Q6 memories */
+	writel_relaxed(Q6SS_CLAMP_IO, drv->base + QDSP6SS_PWR_CTL);
+
+	if (drv->modem_base)
+		pil_q6v4_shutdown_modem();
+
+	if (drv->vreg_enabled) {
+		regulator_disable(drv->vreg);
+		drv->vreg_enabled = false;
+	}
+
+	pil_q6v4_remove_xo_proxy_votes_now(pil->dev);
+
+	return 0;
+}
+
+static struct pil_reset_ops pil_q6v4_ops = {
+	.init_image = pil_q6v4_init_image,
+	.verify_blob = nop_verify_blob,
+	.auth_and_reset = pil_q6v4_reset,
+	.shutdown = pil_q6v4_shutdown,
+};
+
+static int pil_q6v4_init_image_trusted(struct pil_desc *pil,
+		const u8 *metadata, size_t size)
+{
+	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
+	return pas_init_image(pdata->pas_id, metadata, size);
+}
+
+static int pil_q6v4_reset_trusted(struct pil_desc *pil)
+{
+	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
+	int err;
+
+	pil_q6v4_make_xo_proxy_votes(pil->dev);
+
+	err = pil_q6v4_power_up(pil->dev);
+	if (err)
+		return err;
+
+	/* Unhalt bus port */
+	err = msm_bus_axi_portunhalt(pdata->bus_port);
+	if (err)
+		dev_err(pil->dev, "Failed to unhalt bus port\n");
+	return pas_auth_and_reset(pdata->pas_id);
+}
+
+static int pil_q6v4_shutdown_trusted(struct pil_desc *pil)
+{
+	int ret;
+	struct q6v4_data *drv = dev_get_drvdata(pil->dev);
+	struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
+
+	/* Make sure bus port is halted */
+	msm_bus_axi_porthalt(pdata->bus_port);
+
+	ret = pas_shutdown(pdata->pas_id);
+	if (ret)
+		return ret;
+
+	if (drv->vreg_enabled) {
+		regulator_disable(drv->vreg);
+		drv->vreg_enabled = false;
+	}
+
+	pil_q6v4_remove_xo_proxy_votes_now(pil->dev);
+
+	return ret;
+}
+
+static struct pil_reset_ops pil_q6v4_ops_trusted = {
+	.init_image = pil_q6v4_init_image_trusted,
+	.verify_blob = nop_verify_blob,
+	.auth_and_reset = pil_q6v4_reset_trusted,
+	.shutdown = pil_q6v4_shutdown_trusted,
+};
+
+static int __devinit pil_q6v4_driver_probe(struct platform_device *pdev)
+{
+	const struct pil_q6v4_pdata *pdata = pdev->dev.platform_data;
+	struct q6v4_data *drv;
+	struct resource *res;
+	struct pil_desc *desc;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -EINVAL;
+
+	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
+	if (!drv)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, drv);
+
+	drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!drv->base)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (res) {
+		drv->modem_base = devm_ioremap(&pdev->dev, res->start,
+				resource_size(res));
+		if (!drv->modem_base)
+			return -ENOMEM;
+	}
+
+	desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
+	if (!drv)
+		return -ENOMEM;
+
+	desc->name = pdata->name;
+	desc->depends_on = pdata->depends;
+	desc->dev = &pdev->dev;
+
+	if (pas_supported(pdata->pas_id) > 0) {
+		desc->ops = &pil_q6v4_ops_trusted;
+		dev_info(&pdev->dev, "using secure boot\n");
+	} else {
+		desc->ops = &pil_q6v4_ops;
+		dev_info(&pdev->dev, "using non-secure boot\n");
+	}
+
+	drv->vreg = regulator_get(&pdev->dev, "core_vdd");
+	if (IS_ERR(drv->vreg))
+		return PTR_ERR(drv->vreg);
+
+	setup_timer(&drv->xo_timer, pil_q6v4_remove_xo_proxy_votes,
+		    (unsigned long)drv);
+	drv->xo = msm_xo_get(pdata->xo_id, pdata->name);
+	if (IS_ERR(drv->xo))
+		return PTR_ERR(drv->xo);
+
+	if (msm_pil_register(desc)) {
+		regulator_put(drv->vreg);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int __devexit pil_q6v4_driver_exit(struct platform_device *pdev)
+{
+	struct q6v4_data *drv = platform_get_drvdata(pdev);
+	regulator_put(drv->vreg);
+	return 0;
+}
+
+static struct platform_driver pil_q6v4_driver = {
+	.probe = pil_q6v4_driver_probe,
+	.remove = __devexit_p(pil_q6v4_driver_exit),
+	.driver = {
+		.name = "pil_qdsp6v4",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pil_q6v4_init(void)
+{
+	return platform_driver_register(&pil_q6v4_driver);
+}
+module_init(pil_q6v4_init);
+
+static void __exit pil_q6v4_exit(void)
+{
+	platform_driver_unregister(&pil_q6v4_driver);
+}
+module_exit(pil_q6v4_exit);
+
+MODULE_DESCRIPTION("Support for booting QDSP6v4 (Hexagon) processors");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/pil-q6v4.h b/arch/arm/mach-msm/pil-q6v4.h
new file mode 100644
index 0000000..54bdf88
--- /dev/null
+++ b/arch/arm/mach-msm/pil-q6v4.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2011, 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 __MSM_PIL_Q6V4_H
+#define __MSM_PIL_Q6V4_H
+
+struct pil_q6v4_pdata {
+	const unsigned long strap_tcm_base;
+	const unsigned long strap_ahb_upper;
+	const unsigned long strap_ahb_lower;
+	void __iomem *aclk_reg;
+	void __iomem *jtag_clk_reg;
+	const int xo_id;
+	const char *name;
+	const char *depends;
+	const unsigned pas_id;
+	int bus_port;
+};
+#endif
diff --git a/arch/arm/mach-msm/pm-boot.h b/arch/arm/mach-msm/pm-boot.h
index 7e1a439..2234192 100644
--- a/arch/arm/mach-msm/pm-boot.h
+++ b/arch/arm/mach-msm/pm-boot.h
@@ -18,7 +18,14 @@
 	MSM_PM_BOOT_CONFIG_RESET_VECTOR	= 1,
 };
 
+#ifdef CONFIG_PM
 int __init msm_pm_boot_init(int boot_config, uint32_t* address);
+#else
+static inline int __init msm_pm_boot_init(int boot_config, uint32_t* address)
+{
+	return 0;
+}
+#endif
 void msm_pm_boot_config_before_pc(unsigned int cpu, unsigned long entry);
 void msm_pm_boot_config_after_pc(unsigned int cpu);
 
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
index 0b4997c..6e7961c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
@@ -205,6 +205,7 @@
 			break;
 		}
 
+		case MVS_MODE_G711:
 		case MVS_MODE_G711A: {
 			/* G711 frames are 10ms each, but the DSP works with
 			 * 20ms frames and sends two 10ms frames per buffer.
@@ -212,11 +213,16 @@
 			 * buffers.
 			 */
 			/* Remove the first DSP frame info header.
-			 * Header format:
+			 * Header format: G711A
 			 * Bits 0-1: Frame type
 			 * Bits 2-3: Frame rate
+			 *
+			 * Header format: G711
+			 * Bits 2-3: Frame rate
 			 */
-			buf_node->frame.header.frame_type = (*voc_pkt) & 0x03;
+			if (audio->mvs_mode == MVS_MODE_G711A)
+				buf_node->frame.header.frame_type =
+							(*voc_pkt) & 0x03;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			/* There are two frames in the buffer. Length of the
@@ -247,7 +253,8 @@
 				 * Bits 0-1: Frame type
 				 * Bits 2-3: Frame rate
 				 */
-				buf_node->frame.header.frame_type =
+				if (audio->mvs_mode == MVS_MODE_G711A)
+					buf_node->frame.header.frame_type =
 							(*voc_pkt) & 0x03;
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
@@ -271,6 +278,7 @@
 			break;
 		}
 
+		case MVS_MODE_IS733:
 		case MVS_MODE_4GV_NB:
 		case MVS_MODE_4GV_WB: {
 			/* Remove the DSP frame info header.
@@ -284,6 +292,32 @@
 			memcpy(&buf_node->frame.voc_pkt[0],
 				voc_pkt,
 				buf_node->frame.len);
+
+			list_add_tail(&buf_node->list, &audio->out_queue);
+			break;
+		}
+
+		case MVS_MODE_EFR:
+		case MVS_MODE_FR:
+		case MVS_MODE_HR: {
+			/*
+			 * Remove the DSP frame info header
+			 * Header Format
+			 * Bit 0: bfi unused for uplink
+			 * Bit 1-2: sid applies to both uplink and downlink
+			 * Bit 3: taf unused for uplink
+			 * MVS_MODE_HR
+			 * Bit 4: ufi unused for uplink
+			 */
+			buf_node->frame.header.gsm_frame_type.sid =
+						((*voc_pkt) & 0x06) >> 1;
+			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+			buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
+
+			memcpy(&buf_node->frame.voc_pkt[0],
+			voc_pkt,
+			buf_node->frame.len);
+
 			list_add_tail(&buf_node->list, &audio->out_queue);
 			break;
 		}
@@ -353,7 +387,6 @@
 		case MVS_MODE_IS127: {
 			/* Add the DSP frame info header. Header format:
 			 * Bits 0-3: Frame rate
-			 * Bits 4-7: Frame type
 			 */
 			*voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
@@ -423,6 +456,7 @@
 			break;
 		}
 
+		case MVS_MODE_G711:
 		case MVS_MODE_G711A: {
 			/* G711 frames are 10ms each but the DSP expects 20ms
 			 * worth of data, so send two 10ms frames per buffer.
@@ -481,6 +515,7 @@
 			break;
 		}
 
+		case MVS_MODE_IS733:
 		case MVS_MODE_4GV_NB:
 		case MVS_MODE_4GV_WB: {
 			/* Add the DSP frame info header. Header format:
@@ -498,6 +533,48 @@
 			break;
 		}
 
+		case MVS_MODE_EFR:
+		case MVS_MODE_FR:
+		case MVS_MODE_HR: {
+			/*
+			 * Remove the DSP frame info header
+			 * Header Format
+			 * Bit 0: bfi applies only for downlink
+			 * Bit 1-2: sid applies for downlink and uplink
+			 * Bit 3: taf applies only for downlink
+			 * MVS_MODE_HR
+			 * Bit 4: ufi applies only for downlink
+			 */
+			*voc_pkt =
+				((buf_node->frame.header.gsm_frame_type.bfi
+					& 0x01) |
+				((buf_node->frame.header.gsm_frame_type.sid
+					& 0x03) << 1) |
+				((buf_node->frame.header.gsm_frame_type.taf
+					& 0x01) << 3));
+
+			if (audio->mvs_mode == MVS_MODE_HR) {
+				*voc_pkt = (*voc_pkt |
+				((buf_node->frame.header.gsm_frame_type.ufi
+				& 0x01) << 4) |
+				((0 & 0x07) << 5));
+			} else {
+				*voc_pkt = (*voc_pkt |
+				((0 & 0x0F) << 4));
+			}
+
+			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
+
+			memcpy(voc_pkt,
+				&buf_node->frame.voc_pkt[0],
+				buf_node->frame.len);
+
+			list_add_tail(&buf_node->list, &audio->free_in_queue);
+
+			break;
+		}
+
 		default: {
 			*pkt_len = buf_node->frame.len;
 
@@ -523,6 +600,10 @@
 	uint32_t media_type;
 
 	switch (mvs_mode) {
+	case MVS_MODE_IS733:
+		media_type = VSS_MEDIA_ID_13K_MODEM;
+		break;
+
 	case MVS_MODE_IS127:
 		media_type = VSS_MEDIA_ID_EVRC_MODEM;
 		break;
@@ -539,6 +620,18 @@
 		media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
 		break;
 
+	case MVS_MODE_EFR:
+		media_type = VSS_MEDIA_ID_EFR_MODEM;
+		break;
+
+	case MVS_MODE_FR:
+		media_type = VSS_MEDIA_ID_FR_MODEM;
+		break;
+
+	case MVS_MODE_HR:
+		media_type = VSS_MEDIA_ID_HR_MODEM;
+		break;
+
 	case MVS_MODE_LINEAR_PCM:
 		media_type = VSS_MEDIA_ID_PCM_NB;
 		break;
@@ -555,6 +648,7 @@
 		media_type = VSS_MEDIA_ID_G729;
 		break;
 
+	case MVS_MODE_G711:
 	case MVS_MODE_G711A:
 		if (rate_type == MVS_G711A_MODE_MULAW)
 			media_type = VSS_MEDIA_ID_G711_MULAW;
@@ -580,10 +674,15 @@
 	uint32_t network_type;
 
 	switch (mvs_mode) {
+	case MVS_MODE_IS733:
 	case MVS_MODE_IS127:
 	case MVS_MODE_4GV_NB:
 	case MVS_MODE_AMR:
+	case MVS_MODE_EFR:
+	case MVS_MODE_FR:
+	case MVS_MODE_HR:
 	case MVS_MODE_LINEAR_PCM:
+	case MVS_MODE_G711:
 	case MVS_MODE_PCM:
 	case MVS_MODE_G729A:
 	case MVS_MODE_G711A:
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
index 64344ef..c19fd85 100644
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
@@ -404,6 +404,9 @@
 	}
 	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 0, 0);
 
+	if (hdmi_msm_audio_get_sample_rate() != HDMI_SAMPLE_RATE_48KHZ)
+		hdmi_msm_audio_sample_rate_reset(HDMI_SAMPLE_RATE_48KHZ);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 058e281..34169c0 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1117,6 +1117,7 @@
 
 	/* Set encoder properties. */
 	switch (common.mvs_info.media_type) {
+	case VSS_MEDIA_ID_13K_MODEM:
 	case VSS_MEDIA_ID_4GV_NB_MODEM:
 	case VSS_MEDIA_ID_4GV_WB_MODEM:
 	case VSS_MEDIA_ID_EVRC_MODEM: {
@@ -1253,6 +1254,9 @@
 		break;
 	}
 
+	case VSS_MEDIA_ID_EFR_MODEM:
+	case VSS_MEDIA_ID_FR_MODEM:
+	case VSS_MEDIA_ID_HR_MODEM:
 	case VSS_MEDIA_ID_G729:
 	case VSS_MEDIA_ID_G711_ALAW:
 	case VSS_MEDIA_ID_G711_MULAW: {
diff --git a/arch/arm/mach-msm/rpm-regulator.c b/arch/arm/mach-msm/rpm-regulator.c
index c10281b..e2ebbd4 100644
--- a/arch/arm/mach-msm/rpm-regulator.c
+++ b/arch/arm/mach-msm/rpm-regulator.c
@@ -490,6 +490,14 @@
 		 */
 		uV = (uV - range->min_uV + range->step_uV - 1) / range->step_uV;
 		uV = uV * range->step_uV + range->min_uV;
+
+		if (uV > max_uV) {
+			vreg_err(vreg,
+			  "request v=[%d, %d] cannot be met by any set point; "
+			  "next set point: %d\n",
+			  min_uV, max_uV, uV);
+			return -EINVAL;
+		}
 	}
 
 	if (vreg->part->uV.mask) {
@@ -812,6 +820,14 @@
 	uV = (uV - range->min_uV + range->step_uV - 1) / range->step_uV;
 	uV = uV * range->step_uV + range->min_uV;
 
+	if (uV > max_uV) {
+		vreg_err(vreg,
+			"request v=[%d, %d] cannot be met by any set point; "
+			"next set point: %d\n",
+			min_uV, max_uV, uV);
+		return -EINVAL;
+	}
+
 	if (vreg->part->uV.mask) {
 		val[vreg->part->uV.word] = uV << vreg->part->uV.shift;
 		mask[vreg->part->uV.word] = vreg->part->uV.mask;
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 9fe9eea6..3568070 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -928,10 +928,6 @@
 {
 	int rc = 0;
 
-	rc = msm_rpmrs_flush_L2(limits, notify_rpm);
-	if (rc)
-		return rc;
-
 	if (notify_rpm) {
 		rc = msm_rpmrs_flush_buffer(sclk_count, limits, from_idle);
 		if (rc)
@@ -941,6 +937,7 @@
 			msm_mpm_enter_sleep(from_idle);
 	}
 
+	rc = msm_rpmrs_flush_L2(limits, notify_rpm);
 	return rc;
 }
 
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index 8b9abcf..a71aae3 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -298,6 +298,7 @@
 	uint32_t smem_counter;
 
 	struct platform_device *ciq_app_pdev;
+	struct platform_device *csvt_app_pdev;
 
 	wait_queue_head_t   wait_q;
 	int test_completed;
@@ -6162,7 +6163,7 @@
 	int ret;
 
 	pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
-	pr_info(TEST_MODULE_NAME ": init test cahnnel %s.\n", name);
+	pr_info(TEST_MODULE_NAME ": init test channel %s.\n", name);
 
 	ch_id = channel_name_to_id(name);
 	pr_debug(TEST_MODULE_NAME ":id = %d.\n", ch_id);
@@ -6324,6 +6325,35 @@
 	return sdio_test_channel_remove(pdev);
 }
 
+static int sdio_test_channel_csvt_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	if (!pdev)
+		return -ENODEV;
+
+	test_ctx->csvt_app_pdev = platform_device_alloc("SDIO_CSVT_TEST_APP",
+							-1);
+	ret = platform_device_add(test_ctx->csvt_app_pdev);
+		if (ret) {
+			pr_err(MODULE_NAME ":platform_device_add failed, "
+					   "ret=%d\n", ret);
+			return ret;
+		}
+
+	return sdio_test_channel_probe(pdev);
+}
+
+static int sdio_test_channel_csvt_remove(struct platform_device *pdev)
+{
+	if (!pdev)
+		return -ENODEV;
+
+	platform_device_unregister(test_ctx->csvt_app_pdev);
+
+	return sdio_test_channel_remove(pdev);
+}
+
 static struct platform_driver sdio_rpc_drv = {
 	.probe		= sdio_test_channel_probe,
 	.remove		= sdio_test_channel_remove,
@@ -6388,8 +6418,8 @@
 };
 
 static struct platform_driver sdio_csvt_drv = {
-	.probe		= sdio_test_channel_probe,
-	.remove		= sdio_test_channel_remove,
+	.probe		= sdio_test_channel_csvt_probe,
+	.remove		= sdio_test_channel_csvt_remove,
 	.driver		= {
 		.name	= "SDIO_CSVT_TEST",
 		.owner	= THIS_MODULE,
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
index fca88d8..e249d06 100644
--- a/arch/arm/mach-msm/sdio_tty.c
+++ b/arch/arm/mach-msm/sdio_tty.c
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/module.h>
 #include <mach/sdio_al.h>
 
 #define INPUT_SPEED			4800
@@ -24,6 +25,19 @@
 #define SDIO_TTY_MODULE_NAME		"sdio_tty"
 #define SDIO_TTY_MAX_PACKET_SIZE	4096
 #define MAX_SDIO_TTY_DRV		1
+#define MAX_SDIO_TTY_DEVS		2
+#define MAX_SDIO_TTY_DEV_NAME_SIZE	25
+
+/* Configurations per channel device */
+/* CIQ */
+#define SDIO_TTY_CIQ_DEV		"sdio_tty_ciq_0"
+#define SDIO_TTY_CIQ_TEST_DEV		"sdio_tty_ciq_test_0"
+#define SDIO_TTY_CH_CIQ			"SDIO_CIQ"
+
+/* CSVT */
+#define SDIO_TTY_CSVT_DEV		"sdio_tty_csvt_0"
+#define SDIO_TTY_CSVT_TEST_DEV		"sdio_tty_csvt_test_0"
+#define SDIO_TTY_CH_CSVT		"SDIO_CSVT"
 
 enum sdio_tty_state {
 	TTY_INITIAL = 0,
@@ -32,9 +46,27 @@
 	TTY_CLOSED = 3,
 };
 
+enum sdio_tty_devices {
+	SDIO_CIQ,
+	SDIO_CIQ_TEST_APP,
+	SDIO_CSVT,
+	SDIO_CSVT_TEST_APP,
+};
+
+static const struct platform_device_id sdio_tty_id_table[] = {
+	{ "SDIO_CIQ",		SDIO_CIQ },
+	{ "SDIO_CIQ_TEST_APP",	SDIO_CIQ_TEST_APP },
+	{ "SDIO_CSVT",		SDIO_CSVT },
+	{ "SDIO_CSVT_TEST_APP",	SDIO_CSVT_TEST_APP },
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, sdio_tty_id_table);
+
 struct sdio_tty {
 	struct sdio_channel *ch;
 	char *sdio_ch_name;
+	char tty_dev_name[MAX_SDIO_TTY_DEV_NAME_SIZE];
+	int device_id;
 	struct workqueue_struct *workq;
 	struct work_struct work_read;
 	wait_queue_head_t   waitq;
@@ -44,11 +76,21 @@
 	char *read_buf;
 	enum sdio_tty_state sdio_tty_state;
 	int is_sdio_open;
+	int tty_open_count;
 };
 
-static struct sdio_tty *sdio_tty;
+static struct sdio_tty *sdio_tty[MAX_SDIO_TTY_DEVS];
 
-#define DEBUG_MSG(sdio_tty, x...) if (sdio_tty->debug_msg_on) pr_info(x)
+#define DEBUG_MSG(sdio_tty_drv, x...) if (sdio_tty_drv->debug_msg_on) pr_info(x)
+
+/*
+ * Enable sdio_tty debug messages
+ * By default the sdio_tty debug messages are turned off
+ */
+static int ciq_debug_msg_on;
+module_param(ciq_debug_msg_on, int, 0);
+static int csvt_debug_msg_on;
+module_param(csvt_debug_msg_on, int, 0);
 
 static void sdio_tty_read(struct work_struct *work)
 {
@@ -62,30 +104,30 @@
 	sdio_tty_drv = container_of(work, struct sdio_tty, work_read);
 
 	if (!sdio_tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty", __func__);
 		return ;
 	}
 
 	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-		       __func__, sdio_tty_drv->sdio_tty_state);
+			__func__, sdio_tty_drv->sdio_tty_state);
 		return;
 	}
 
 	if (!sdio_tty_drv->read_buf) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL read_buf", __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL read_buf for dev %s",
+			__func__, sdio_tty_drv->tty_dev_name);
 		return;
 	}
 
-	/* Read the data from teh SDIO channel as long as there is available
+	/* Read the data from the SDIO channel as long as there is available
 	   data */
 	while (1) {
 		if (test_bit(TTY_THROTTLED, &sdio_tty_drv->tty_str->flags)) {
-			DEBUG_MSG(sdio_tty_drv,
-				  SDIO_TTY_MODULE_NAME ": %s: TTY_THROTTLED bit"
-						       " is set, exit",
-				  __func__);
+			DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
+					": %s: TTY_THROTTLED bit is set for "
+					"dev %s, exit", __func__,
+					sdio_tty_drv->tty_dev_name);
 			return;
 		}
 
@@ -93,20 +135,22 @@
 		read_avail = sdio_read_avail(sdio_tty_drv->ch);
 
 		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
-					     ": %s: read_avail is %d", __func__,
-					     read_avail);
+				": %s: read_avail is %d for dev %s", __func__,
+				read_avail, sdio_tty_drv->tty_dev_name);
 
 		if (read_avail == 0) {
-			DEBUG_MSG(sdio_tty_drv,
-				  SDIO_TTY_MODULE_NAME ": %s: read_avail is 0",
-				  __func__);
+			DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
+					": %s: read_avail is 0 for dev %s",
+					__func__, sdio_tty_drv->tty_dev_name);
 			return;
 		}
 
 		if (read_avail > SDIO_TTY_MAX_PACKET_SIZE) {
 			pr_err(SDIO_TTY_MODULE_NAME ": %s: read_avail(%d) is "
-				"bigger than SDIO_TTY_MAX_PACKET_SIZE(%d)",
-			       __func__, read_avail, SDIO_TTY_MAX_PACKET_SIZE);
+				"bigger than SDIO_TTY_MAX_PACKET_SIZE(%d) "
+				"for dev %s", __func__, read_avail,
+				SDIO_TTY_MAX_PACKET_SIZE,
+				sdio_tty_drv->tty_dev_name);
 			return;
 		}
 
@@ -114,8 +158,9 @@
 				sdio_tty_drv->read_buf,
 				read_avail);
 		if (ret < 0) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_read error(%d)",
-			       __func__, ret);
+			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_read error(%d) "
+				"for dev %s", __func__, ret,
+				sdio_tty_drv->tty_dev_name);
 			return;
 		}
 
@@ -132,15 +177,17 @@
 
 		if (total_push != read_avail) {
 			pr_err(SDIO_TTY_MODULE_NAME ": %s: failed, total_push"
-						    "(%d) != read_avail(%d)\n",
-			       __func__, total_push, read_avail);
+				"(%d) != read_avail(%d) for dev %s\n",
+				__func__, total_push, read_avail,
+				sdio_tty_drv->tty_dev_name);
 		}
 
 		tty_flip_buffer_push(sdio_tty_drv->tty_str);
 
-		DEBUG_MSG(sdio_tty_drv,
-			  SDIO_TTY_MODULE_NAME ": %s: End of read %d bytes",
-				__func__, read_avail);
+		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME
+				": %s: End of read %d bytes for dev %s",
+				__func__, read_avail,
+				sdio_tty_drv->tty_dev_name);
 	}
 }
 
@@ -159,27 +206,26 @@
 	struct sdio_tty *sdio_tty_drv = NULL;
 
 	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
 		return -ENODEV;
 	}
 	sdio_tty_drv = tty->driver_data;
 	if (!sdio_tty_drv) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
+			__func__);
 		return -ENODEV;
 	}
 
 	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-		       __func__, sdio_tty_drv->sdio_tty_state);
+			__func__, sdio_tty_drv->sdio_tty_state);
 		return -EPERM;
 	}
 
 	write_avail = sdio_write_avail(sdio_tty_drv->ch);
-	DEBUG_MSG(sdio_tty_drv,
-		  SDIO_TTY_MODULE_NAME ": %s: write_avail=%d",
-		 __func__, write_avail);
+	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: write_avail=%d "
+			"for dev %s", __func__, write_avail,
+			sdio_tty_drv->tty_dev_name);
 
 	return write_avail;
 }
@@ -205,60 +251,60 @@
 	struct sdio_tty *sdio_tty_drv = NULL;
 
 	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
 		return -ENODEV;
 	}
 	sdio_tty_drv = tty->driver_data;
 	if (!sdio_tty_drv) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
+			__func__);
 		return -ENODEV;
 	}
 
 	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-		       __func__, sdio_tty_drv->sdio_tty_state);
+			__func__, sdio_tty_drv->sdio_tty_state);
 		return -EPERM;
 	}
 
-	DEBUG_MSG(sdio_tty_drv,
-		  SDIO_TTY_MODULE_NAME ": %s: WRITING CALLBACK CALLED WITH "
-				       "%d bytes\n",
-		 __func__, count);
+	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Write Callback "
+			"called with %d bytes for dev %s\n", __func__, count,
+			sdio_tty_drv->tty_dev_name);
 	write_avail = sdio_write_avail(sdio_tty_drv->ch);
 	if (write_avail == 0) {
-		DEBUG_MSG(sdio_tty_drv,
-			  SDIO_TTY_MODULE_NAME ": %s: write_avail is 0\n",
-			 __func__);
+		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
+				"write_avail is 0 for dev %s\n",
+				__func__, sdio_tty_drv->tty_dev_name);
 		return 0;
 	}
 	if (write_avail > SDIO_TTY_MAX_PACKET_SIZE) {
-		DEBUG_MSG(sdio_tty_drv,
-			  SDIO_TTY_MODULE_NAME ": %s: write_avail(%d) is "
-			  "bigger than max packet size,(%d), setting to "
-			  "max_packet_size\n",
-			  __func__, write_avail, SDIO_TTY_MAX_PACKET_SIZE);
+		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
+				"write_avail(%d) is bigger than max packet "
+				"size(%d) for dev %s, setting to "
+				"max_packet_size\n", __func__, write_avail,
+				SDIO_TTY_MAX_PACKET_SIZE,
+				sdio_tty_drv->tty_dev_name);
 		write_avail = SDIO_TTY_MAX_PACKET_SIZE;
 	}
 	if (write_avail < count) {
-		DEBUG_MSG(sdio_tty_drv,
-			  SDIO_TTY_MODULE_NAME ": %s: write_avail(%d) is "
-					       "smaller than "
-				    "required(%d), writing only %d bytes\n",
-			 __func__, write_avail, count, write_avail);
+		DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: "
+				"write_avail(%d) is smaller than required(%d) "
+				"for dev %s, writing only %d bytes\n",
+				__func__, write_avail, count,
+				sdio_tty_drv->tty_dev_name, write_avail);
 		len = write_avail;
 	}
 	ret = sdio_write(sdio_tty_drv->ch, buf, len);
 	if (ret) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_write failed, ret=%d\n",
-			 __func__, ret);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_write failed for "
+			"dev %s, ret=%d\n", __func__,
+			sdio_tty_drv->tty_dev_name, ret);
 		return 0;
 	}
 
-	DEBUG_MSG(sdio_tty_drv,
-		  SDIO_TTY_MODULE_NAME ": %s: End of function, len=%d bytes\n",
-		 __func__, len);
+	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: End of function, "
+			"dev=%s, len=%d bytes\n", __func__,
+			sdio_tty_drv->tty_dev_name, len);
 
 	return len;
 }
@@ -269,18 +315,18 @@
 
 	if (!sdio_tty_drv) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
-		       __func__);
+			__func__);
 	}
 
 	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_state = %d",
-		       __func__, sdio_tty_drv->sdio_tty_state);
+			__func__, sdio_tty_drv->sdio_tty_state);
 		return;
 	}
 
-	DEBUG_MSG(sdio_tty_drv,
-		  SDIO_TTY_MODULE_NAME ": %s: event %d received\n", __func__,
-		  event);
+	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: event %d "
+			"received for dev %s\n", __func__, event,
+			sdio_tty_drv->tty_dev_name);
 
 	if (event == SDIO_EVENT_DATA_READ_AVAIL)
 		queue_work(sdio_tty_drv->workq, &sdio_tty_drv->work_read);
@@ -298,20 +344,37 @@
 static int sdio_tty_open(struct tty_struct *tty, struct file *file)
 {
 	int ret = 0;
+	int i = 0;
 	struct sdio_tty *sdio_tty_drv = NULL;
 
 	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
 		return -ENODEV;
 	}
-	sdio_tty_drv = sdio_tty;
+
+	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+		if (sdio_tty[i] == NULL)
+			continue;
+		if (!strncmp(sdio_tty[i]->tty_dev_name, tty->name,
+				MAX_SDIO_TTY_DEV_NAME_SIZE)) {
+			sdio_tty_drv = sdio_tty[i];
+			break;
+		}
+	}
+
 	if (!sdio_tty_drv) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
 		       __func__);
 		return -ENODEV;
 	}
 
+	sdio_tty_drv->tty_open_count++;
+	if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) is already open",
+			__func__, sdio_tty_drv->tty_dev_name);
+		return -EBUSY;
+	}
+
 	tty->driver_data = sdio_tty_drv;
 
 	sdio_tty_drv->tty_str = tty;
@@ -321,36 +384,31 @@
 
 	sdio_tty_drv->read_buf = kzalloc(SDIO_TTY_MAX_PACKET_SIZE, GFP_KERNEL);
 	if (sdio_tty_drv->read_buf == NULL) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate read_buf",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate read_buf "
+			"for dev %s", __func__, sdio_tty_drv->tty_dev_name);
 		return -ENOMEM;
 	}
 
 	sdio_tty_drv->workq = create_singlethread_workqueue("sdio_tty_read");
 	if (!sdio_tty_drv->workq) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to create workq",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to create workq "
+			"for dev %s", __func__, sdio_tty_drv->tty_dev_name);
 		return -ENOMEM;
 	}
 
-	if (sdio_tty_drv->sdio_tty_state == TTY_OPENED) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty is already open",
-		       __func__);
-		return -EBUSY;
-	}
-
 	if (!sdio_tty_drv->is_sdio_open) {
 		ret = sdio_open(sdio_tty_drv->sdio_ch_name, &sdio_tty_drv->ch,
 				sdio_tty_drv, sdio_tty_notify);
 		if (ret < 0) {
-			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_open err=%d\n",
-			       __func__, ret);
+			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_open err=%d "
+				"for dev %s\n", __func__, ret,
+				sdio_tty_drv->tty_dev_name);
 			destroy_workqueue(sdio_tty_drv->workq);
 			return ret;
 		}
 
-		pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel opened\n",
-			__func__);
+		pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel(%s) opened "
+			"\n", __func__, sdio_tty_drv->sdio_ch_name);
 
 		sdio_tty_drv->is_sdio_open = 1;
 	} else {
@@ -363,8 +421,8 @@
 
 	sdio_tty_drv->sdio_tty_state = TTY_OPENED;
 
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: TTY device opened\n",
-		__func__);
+	pr_info(SDIO_TTY_MODULE_NAME ": %s: TTY device(%s) opened\n",
+		__func__, sdio_tty_drv->tty_dev_name);
 
 	return ret;
 }
@@ -385,8 +443,7 @@
 	struct sdio_tty *sdio_tty_drv = NULL;
 
 	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
 		return;
 	}
 	sdio_tty_drv = tty->driver_data;
@@ -397,10 +454,11 @@
 	}
 	if (sdio_tty_drv->sdio_tty_state != TTY_OPENED) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: trying to close a "
-					    "TTY device that was not opened\n",
-		       __func__);
+			"TTY device that was not opened\n", __func__);
 		return;
 	}
+	if (--sdio_tty_drv->tty_open_count != 0)
+		return;
 
 	flush_workqueue(sdio_tty_drv->workq);
 	destroy_workqueue(sdio_tty_drv->workq);
@@ -410,8 +468,8 @@
 
 	sdio_tty_drv->sdio_tty_state = TTY_CLOSED;
 
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY channel closed\n",
-		__func__);
+	pr_info(SDIO_TTY_MODULE_NAME ": %s: SDIO_TTY device(%s) closed\n",
+		__func__, sdio_tty_drv->tty_dev_name);
 }
 
 static void sdio_tty_unthrottle(struct tty_struct *tty)
@@ -419,8 +477,7 @@
 	struct sdio_tty *sdio_tty_drv = NULL;
 
 	if (!tty) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty",
-		       __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL tty", __func__);
 		return;
 	}
 	sdio_tty_drv = tty->driver_data;
@@ -448,33 +505,53 @@
 	.unthrottle = sdio_tty_unthrottle,
 };
 
-void *sdio_tty_init_tty(char *tty_name, char *sdio_ch_name)
+int sdio_tty_init_tty(char *tty_name, char *sdio_ch_name,
+			enum sdio_tty_devices device_id, int debug_msg_on)
 {
 	int ret = 0;
-	struct device *tty_dev;
-	struct sdio_tty *sdio_tty_drv;
-
-	pr_info(SDIO_TTY_MODULE_NAME ": %s\n", __func__);
+	int i = 0;
+	struct device *tty_dev = NULL;
+	struct sdio_tty *sdio_tty_drv = NULL;
 
 	sdio_tty_drv = kzalloc(sizeof(struct sdio_tty), GFP_KERNEL);
 	if (sdio_tty_drv == NULL) {
-		pr_err(SDIO_TTY_MODULE_NAME "%s: failed to allocate sdio_tty",
-		       __func__);
-		return NULL;
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: failed to allocate sdio_tty "
+			"for dev %s", __func__, tty_name);
+		return -ENOMEM;
 	}
 
-	sdio_tty = sdio_tty_drv;
+	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+		if (sdio_tty[i] == NULL) {
+			sdio_tty[i] = sdio_tty_drv;
+			break;
+		}
+	}
+
+	if (i == MAX_SDIO_TTY_DEVS) {
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty dev(%s) creation failed,"
+			" max limit(%d) reached.", __func__, tty_name,
+			MAX_SDIO_TTY_DEVS);
+		kfree(sdio_tty_drv);
+		return -ENODEV;
+	}
+
+	snprintf(sdio_tty_drv->tty_dev_name, MAX_SDIO_TTY_DEV_NAME_SIZE,
+			"%s%d", tty_name, 0);
 	sdio_tty_drv->sdio_ch_name = sdio_ch_name;
+	sdio_tty_drv->device_id = device_id;
+	pr_info(SDIO_TTY_MODULE_NAME ": %s: dev=%s, id=%d, channel=%s\n",
+		__func__, sdio_tty_drv->tty_dev_name, sdio_tty_drv->device_id,
+		sdio_tty_drv->sdio_ch_name);
 
 	INIT_WORK(&sdio_tty_drv->work_read, sdio_tty_read);
 
 	sdio_tty_drv->tty_drv = alloc_tty_driver(MAX_SDIO_TTY_DRV);
 
 	if (!sdio_tty_drv->tty_drv) {
-		pr_err(SDIO_TTY_MODULE_NAME ": %s - tty_drv is NULL",
-				   __func__);
+		pr_err(SDIO_TTY_MODULE_NAME ": %s - tty_drv is NULL for dev %s",
+			__func__, sdio_tty_drv->tty_dev_name);
 		kfree(sdio_tty_drv);
-		return NULL;
+		return -ENODEV;
 	}
 
 	sdio_tty_drv->tty_drv->name = tty_name;
@@ -500,31 +577,38 @@
 	if (ret) {
 		put_tty_driver(sdio_tty_drv->tty_drv);
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_driver() "
-					    "failed\n", __func__);
+			"failed for dev %s\n", __func__,
+			sdio_tty_drv->tty_dev_name);
 
 		sdio_tty_drv->tty_drv = NULL;
 		kfree(sdio_tty_drv);
-		return NULL;
+		return -ENODEV;
 	}
 
 	tty_dev = tty_register_device(sdio_tty_drv->tty_drv, 0, NULL);
 	if (IS_ERR(tty_dev)) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: tty_register_device() "
-			"failed\n", __func__);
+			"failed for dev %s\n", __func__,
+			sdio_tty_drv->tty_dev_name);
 		tty_unregister_driver(sdio_tty_drv->tty_drv);
 		put_tty_driver(sdio_tty_drv->tty_drv);
 		kfree(sdio_tty_drv);
-		return NULL;
+		return -ENODEV;
 	}
 
 	sdio_tty_drv->sdio_tty_state = TTY_REGISTERED;
-	return sdio_tty_drv;
+	if (debug_msg_on) {
+		pr_info(SDIO_TTY_MODULE_NAME ": %s: turn on debug msg for %s",
+			__func__, sdio_tty_drv->tty_dev_name);
+		sdio_tty_drv->debug_msg_on = debug_msg_on;
+	}
+	return 0;
 }
-EXPORT_SYMBOL(sdio_tty_init_tty);
 
 int sdio_tty_uninit_tty(void *sdio_tty_handle)
 {
 	int ret = 0;
+	int i = 0;
 	struct sdio_tty *sdio_tty_drv = sdio_tty_handle;
 
 	if (!sdio_tty_drv) {
@@ -546,51 +630,151 @@
 		ret = tty_unregister_driver(sdio_tty_drv->tty_drv);
 		if (ret) {
 			pr_err(SDIO_TTY_MODULE_NAME ": %s: "
-			    "tty_unregister_driver() failed\n", __func__);
+				"tty_unregister_driver() failed for dev %s\n",
+				__func__, sdio_tty_drv->tty_dev_name);
 		}
 		put_tty_driver(sdio_tty_drv->tty_drv);
 		sdio_tty_drv->sdio_tty_state = TTY_INITIAL;
 		sdio_tty_drv->tty_drv = NULL;
 	}
 
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: Freeing sdio_tty structure",
-		__func__);
+	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+		if (sdio_tty[i] == NULL)
+			continue;
+		if (sdio_tty[i]->device_id == sdio_tty_drv->device_id) {
+			sdio_tty[i] = NULL;
+			break;
+		}
+	}
+
+	DEBUG_MSG(sdio_tty_drv, SDIO_TTY_MODULE_NAME ": %s: Freeing sdio_tty "
+			"structure, dev=%s", __func__,
+			sdio_tty_drv->tty_dev_name);
 	kfree(sdio_tty_drv);
 
 	return 0;
 }
-EXPORT_SYMBOL(sdio_tty_uninit_tty);
 
-
-void sdio_tty_enable_debug_msg(void *sdio_tty_handle, int enable)
+static int sdio_tty_probe(struct platform_device *pdev)
 {
-	struct sdio_tty *sdio_tty_drv = sdio_tty_handle;
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	enum sdio_tty_devices device_id = id->driver_data;
+	char *device_name = NULL;
+	char *channel_name = NULL;
+	int debug_msg_on = 0;
+	int ret = 0;
+
+	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
+
+	switch (device_id) {
+	case SDIO_CIQ:
+		device_name = SDIO_TTY_CIQ_DEV;
+		channel_name = SDIO_TTY_CH_CIQ;
+		debug_msg_on = ciq_debug_msg_on;
+		break;
+	case SDIO_CIQ_TEST_APP:
+		device_name = SDIO_TTY_CIQ_TEST_DEV;
+		channel_name = SDIO_TTY_CH_CIQ;
+		debug_msg_on = ciq_debug_msg_on;
+		break;
+	case SDIO_CSVT:
+		device_name = SDIO_TTY_CSVT_DEV;
+		channel_name = SDIO_TTY_CH_CSVT;
+		debug_msg_on = csvt_debug_msg_on;
+		break;
+	case SDIO_CSVT_TEST_APP:
+		device_name = SDIO_TTY_CSVT_TEST_DEV;
+		channel_name = SDIO_TTY_CH_CSVT;
+		debug_msg_on = csvt_debug_msg_on;
+		break;
+	default:
+		pr_err(SDIO_TTY_MODULE_NAME ": %s Invalid device:%s, id:%d",
+			__func__, pdev->name, device_id);
+		ret = -ENODEV;
+		break;
+	}
+
+	if (device_name) {
+		ret = sdio_tty_init_tty(device_name, channel_name,
+					device_id, debug_msg_on);
+		if (ret) {
+			pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_init_tty "
+				"failed for dev:%s", __func__, device_name);
+		}
+	}
+	return ret;
+}
+
+static int sdio_tty_remove(struct platform_device *pdev)
+{
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	enum sdio_tty_devices device_id = id->driver_data;
+	struct sdio_tty *sdio_tty_drv = NULL;
+	int i = 0;
+	int ret = 0;
+
+	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
+
+	for (i = 0; i < MAX_SDIO_TTY_DEVS; i++) {
+		if (sdio_tty[i] == NULL)
+			continue;
+		if (sdio_tty[i]->device_id == device_id) {
+			sdio_tty_drv = sdio_tty[i];
+			break;
+		}
+	}
 
 	if (!sdio_tty_drv) {
 		pr_err(SDIO_TTY_MODULE_NAME ": %s: NULL sdio_tty_drv",
 		       __func__);
-		return;
+		return -ENODEV;
 	}
-	pr_info(SDIO_TTY_MODULE_NAME ": %s: setting debug_msg_on to %d",
-		       __func__, enable);
-	sdio_tty_drv->debug_msg_on = enable;
+
+	ret = sdio_tty_uninit_tty(sdio_tty_drv);
+	if (ret) {
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: sdio_tty_uninit_tty "
+			"failed for %s", __func__, pdev->name);
+	}
+	return ret;
 }
-EXPORT_SYMBOL(sdio_tty_enable_debug_msg);
 
+static struct platform_driver sdio_tty_pdrv = {
+	.probe		= sdio_tty_probe,
+	.remove		= sdio_tty_remove,
+	.id_table	= sdio_tty_id_table,
+	.driver		= {
+		.name	= "SDIO_TTY",
+		.owner	= THIS_MODULE,
+	},
+};
 
+/*
+ *  Module Init.
+ *
+ *  Register SDIO TTY driver.
+ *
+ */
 static int __init sdio_tty_init(void)
 {
-	return 0;
+	int ret = 0;
+
+	ret = platform_driver_register(&sdio_tty_pdrv);
+	if (ret) {
+		pr_err(SDIO_TTY_MODULE_NAME ": %s: platform_driver_register "
+					    "failed", __func__);
+	}
+	return ret;
 };
 
 /*
  *  Module Exit.
  *
- *  Unregister SDIO driver.
+ *  Unregister SDIO TTY driver.
  *
  */
 static void __exit sdio_tty_exit(void)
 {
+	platform_driver_unregister(&sdio_tty_pdrv);
 }
 
 module_init(sdio_tty_init);
diff --git a/arch/arm/mach-msm/sdio_tty_ciq.c b/arch/arm/mach-msm/sdio_tty_ciq.c
deleted file mode 100644
index 64b772d..0000000
--- a/arch/arm/mach-msm/sdio_tty_ciq.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Copyright (c) 2011, 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/slab.h>
-#include <linux/platform_device.h>
-#include <linux/debugfs.h>
-#include <mach/sdio_al.h>
-#include <mach/sdio_tty.h>
-
-#define SDIO_TTY_DEV		"sdio_tty_ciq_0"
-#define SDIO_CIQ		"sdio_ciq"
-#define SDIO_TTY_DEV_TEST	"sdio_tty_ciq_test_0"
-#define TTY_CIQ_MODULE_NAME	"sdio_tty_ciq"
-
-struct sdio_tty_ciq {
-	void *sdio_tty_handle;
-};
-
-static struct sdio_tty_ciq sdio_tty_ciq;
-
-/*
- * Enable sdio_tty debug messages
- * By default the sdio_tty debug messages are turned off
- */
-static int debug_msg_on;
-module_param(debug_msg_on, int, 0);
-
-static int sdio_tty_probe(struct platform_device *pdev)
-{
-	sdio_tty_ciq.sdio_tty_handle = sdio_tty_init_tty(SDIO_TTY_DEV,
-							 "SDIO_CIQ");
-	if (!sdio_tty_ciq.sdio_tty_handle) {
-		pr_err(TTY_CIQ_MODULE_NAME ": %s: NULL sdio_tty_handle",
-		       __func__);
-		return -ENODEV;
-	}
-
-	if (debug_msg_on)
-		sdio_tty_enable_debug_msg(sdio_tty_ciq.sdio_tty_handle,
-					  debug_msg_on);
-
-	return 0;
-}
-
-static int sdio_tty_test_probe(struct platform_device *pdev)
-{
-	sdio_tty_ciq.sdio_tty_handle = sdio_tty_init_tty(SDIO_TTY_DEV_TEST,
-							 "SDIO_CIQ");
-	if (!sdio_tty_ciq.sdio_tty_handle) {
-		pr_err(TTY_CIQ_MODULE_NAME ": %s: NULL sdio_tty_handle",
-		       __func__);
-		return -ENODEV;
-	}
-
-	if (debug_msg_on)
-		sdio_tty_enable_debug_msg(sdio_tty_ciq.sdio_tty_handle,
-					  debug_msg_on);
-
-	return 0;
-}
-
-static int sdio_tty_remove(struct platform_device *pdev)
-{
-	int ret = 0;
-
-	pr_info(TTY_CIQ_MODULE_NAME ": %s", __func__);
-	ret = sdio_tty_uninit_tty(sdio_tty_ciq.sdio_tty_handle);
-	if (ret) {
-		pr_err(TTY_CIQ_MODULE_NAME ": %s: sdio_tty_uninit_tty failed",
-		       __func__);
-		return ret;
-	}
-
-	return 0;
-}
-
-static struct platform_driver sdio_tty_pdrv = {
-	.probe		= sdio_tty_probe,
-	.remove		= sdio_tty_remove,
-	.driver		= {
-		.name	= "SDIO_CIQ",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static struct platform_driver sdio_tty_test_pdrv = {
-	.probe		= sdio_tty_test_probe,
-	.remove		= sdio_tty_remove,
-	.driver		= {
-		.name	= "SDIO_CIQ_TEST_APP",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdio_tty_ciq_init(void)
-{
-	int ret = 0;
-
-	ret = platform_driver_register(&sdio_tty_pdrv);
-	if (ret) {
-		pr_err(TTY_CIQ_MODULE_NAME ": %s: platform_driver_register "
-					    "failed", __func__);
-		return ret;
-	}
-	return platform_driver_register(&sdio_tty_test_pdrv);
-};
-
-/*
- *  Module Exit.
- *
- *  Unregister SDIO driver.
- *
- */
-static void __exit sdio_tty_ciq_exit(void)
-{
-	platform_driver_unregister(&sdio_tty_pdrv);
-	platform_driver_unregister(&sdio_tty_test_pdrv);
-}
-
-module_init(sdio_tty_ciq_init);
-module_exit(sdio_tty_ciq_exit);
-
-MODULE_DESCRIPTION("SDIO TTY CIQ");
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Maya Erez <merez@codeaurora.org>");
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index e794801..691dad2 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -660,9 +660,11 @@
 	if (smsm_info.state) {
 		writel_relaxed(0, SMSM_STATE_ADDR(restart_pid));
 
-		/* clear apps SMSM to restart SMSM init handshake */
-		if (restart_pid == SMSM_MODEM)
-			writel_relaxed(0, SMSM_STATE_ADDR(SMSM_APPS));
+		/* restart SMSM init handshake */
+		if (restart_pid == SMSM_MODEM) {
+			smsm_change_state(SMSM_APPS_STATE,
+					SMSM_INIT | SMSM_SMD_LOOPBACK, 0);
+		}
 
 		/* notify SMSM processors */
 		smsm_irq_handler(0, 0);
@@ -2541,8 +2543,10 @@
 				  void *data);
 
 static struct restart_notifier_block restart_notifiers[] = {
-	{SMSM_MODEM, "modem", .nb.notifier_call = restart_notifier_cb},
-	{SMSM_Q6, "lpass", .nb.notifier_call = restart_notifier_cb},
+	{SMD_MODEM, "modem", .nb.notifier_call = restart_notifier_cb},
+	{SMD_Q6, "lpass", .nb.notifier_call = restart_notifier_cb},
+	{SMD_WCNSS, "riva", .nb.notifier_call = restart_notifier_cb},
+	{SMD_DSPS, "dsps", .nb.notifier_call = restart_notifier_cb},
 };
 
 static int restart_notifier_cb(struct notifier_block *this,
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index c4bc76c..87b6d3f 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -217,6 +217,13 @@
 
 	/* 8930 IDs */
 	[116] = MSM_CPU_8930,
+	[117] = MSM_CPU_8930,
+	[118] = MSM_CPU_8930,
+	[119] = MSM_CPU_8930,
+
+	/* 8627 IDs */
+	[120] = MSM_CPU_8627,
+	[121] = MSM_CPU_8627,
 
 	/* 8660A ID */
 	[122] = MSM_CPU_8960,
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 9647646..f076a10 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1020,12 +1020,13 @@
 		gpt->freq = 32765;
 		gpt_hz = 32765;
 		sclk_hz = 32765;
-		gpt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
-		dgt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
+		if (!machine_is_apq8064_rumi3()) {
+			gpt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
+			dgt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
+		}
 	} else {
 		WARN_ON("Timer running on unknown hardware. Configure this! "
 			"Assuming default configuration.\n");
-		global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
 		dgt->freq = 6750000;
 	}
 
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
index 8f782a9..cffa5c7 100644
--- a/arch/arm/mach-msm/vreg.c
+++ b/arch/arm/mach-msm/vreg.c
@@ -18,7 +18,12 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/atomic.h>
 #include <linux/debugfs.h>
+#include <linux/regulator/consumer.h>
 #include <linux/string.h>
 #include <mach/vreg.h>
 
@@ -33,173 +38,187 @@
 #endif
 
 struct vreg {
-	const char *name;
-	unsigned id;
-	int status;
-	unsigned refcnt;
+	struct list_head	list;
+	struct mutex		lock;
+	const char		*name;
+	u64			refcnt;
+	unsigned		mv;
+	struct regulator	*reg;
 };
 
-#define VREG(_name, _id, _status, _refcnt) \
-	{ .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
+static LIST_HEAD(vreg_list);
+static DEFINE_MUTEX(vreg_lock);
 
-static struct vreg vregs[] = {
-	VREG("msma",	0, 0, 0),
-	VREG("msmp",	1, 0, 0),
-	VREG("msme1",	2, 0, 0),
-	VREG("msmc1",	3, 0, 0),
-	VREG("msmc2",	4, 0, 0),
-	VREG("gp3",	5, 0, 0),
-	VREG("msme2",	6, 0, 0),
-	VREG("gp4",	7, 0, 0),
-	VREG("gp1",	8, 0, 0),
-	VREG("tcxo",	9, 0, 0),
-	VREG("pa",	10, 0, 0),
-	VREG("rftx",	11, 0, 0),
-	VREG("rfrx1",	12, 0, 0),
-	VREG("rfrx2",	13, 0, 0),
-	VREG("synt",	14, 0, 0),
-	VREG("wlan",	15, 0, 0),
-	VREG("usb",	16, 0, 0),
-	VREG("boost",	17, 0, 0),
-	VREG("mmc",	18, 0, 0),
-	VREG("ruim",	19, 0, 0),
-	VREG("msmc0",	20, 0, 0),
-	VREG("gp2",	21, 0, 0),
-	VREG("gp5",	22, 0, 0),
-	VREG("gp6",	23, 0, 0),
-	VREG("rf",	24, 0, 0),
-	VREG("rf_vco",	26, 0, 0),
-	VREG("mpll",	27, 0, 0),
-	VREG("s2",	28, 0, 0),
-	VREG("s3",	29, 0, 0),
-	VREG("rfubm",	30, 0, 0),
-	VREG("ncp",	31, 0, 0),
-	VREG("gp7",	32, 0, 0),
-	VREG("gp8",	33, 0, 0),
-	VREG("gp9",	34, 0, 0),
-	VREG("gp10",	35, 0, 0),
-	VREG("gp11",	36, 0, 0),
-	VREG("gp12",	37, 0, 0),
-	VREG("gp13",	38, 0, 0),
-	VREG("gp14",	39, 0, 0),
-	VREG("gp15",	40, 0, 0),
-	VREG("gp16",	41, 0, 0),
-	VREG("gp17",	42, 0, 0),
-	VREG("s4",	43, 0, 0),
-	VREG("usb2",	44, 0, 0),
-	VREG("wlan2",	45, 0, 0),
-	VREG("xo_out",	46, 0, 0),
-	VREG("lvsw0",	47, 0, 0),
-	VREG("lvsw1",	48, 0, 0),
-	VREG("mddi",	49, 0, 0),
-	VREG("pllx",	50, 0, 0),
-	VREG("wlan3",	51, 0, 0),
-	VREG("emmc",	52, 0,	0),
-	VREG("wlan_tcx0", 53, 0, 0),
-	VREG("usim2",	54, 0, 0),
-	VREG("usim",	55, 0, 0),
-	VREG("bt",	56, 0, 0),
-	VREG("wlan4",	57, 0, 0),
-};
+#ifdef CONFIG_DEBUG_FS
+static void vreg_add_debugfs(struct vreg *vreg);
+#else
+static inline void vreg_add_debugfs(struct vreg *vreg) { }
+#endif
+
+static struct vreg *vreg_create(const char *id)
+{
+	int rc;
+	struct vreg *vreg;
+
+	vreg = kzalloc(sizeof(*vreg), GFP_KERNEL);
+	if (!vreg) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	INIT_LIST_HEAD(&vreg->list);
+	mutex_init(&vreg->lock);
+
+	vreg->reg = regulator_get(NULL, id);
+	if (IS_ERR(vreg->reg)) {
+		rc = PTR_ERR(vreg->reg);
+		goto free_vreg;
+	}
+
+	vreg->name = kstrdup(id, GFP_KERNEL);
+	if (!vreg->name) {
+		rc = -ENOMEM;
+		goto put_reg;
+	}
+
+	list_add_tail(&vreg->list, &vreg_list);
+	vreg_add_debugfs(vreg);
+
+	return vreg;
+
+put_reg:
+	regulator_put(vreg->reg);
+free_vreg:
+	kfree(vreg);
+error:
+	return ERR_PTR(rc);
+}
+
+static void vreg_destroy(struct vreg *vreg)
+{
+	if (!vreg)
+		return;
+
+	if (vreg->refcnt)
+		regulator_disable(vreg->reg);
+
+	kfree(vreg->name);
+	regulator_put(vreg->reg);
+	kfree(vreg);
+}
 
 struct vreg *vreg_get(struct device *dev, const char *id)
 {
-	int n;
-	for (n = 0; n < ARRAY_SIZE(vregs); n++) {
-		if (!strcmp(vregs[n].name, id))
-			return vregs + n;
+	struct vreg *vreg = NULL;
+
+	if (!id)
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&vreg_lock);
+	list_for_each_entry(vreg, &vreg_list, list) {
+		if (!strncmp(vreg->name, id, 10))
+			goto ret;
 	}
-	return ERR_PTR(-ENOENT);
+
+	vreg = vreg_create(id);
+
+ret:
+	mutex_unlock(&vreg_lock);
+	return vreg;
 }
 EXPORT_SYMBOL(vreg_get);
 
 void vreg_put(struct vreg *vreg)
 {
+	kfree(vreg->name);
+	regulator_put(vreg->reg);
 }
 
 int vreg_enable(struct vreg *vreg)
 {
-	unsigned id = vreg->id;
-	int enable = VREG_SWITCH_ENABLE;
+	int rc = 0;
+	if (!vreg)
+		return -ENODEV;
 
-	if (vreg->refcnt == 0)
-		vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+	mutex_lock(&vreg->lock);
+	if (vreg->refcnt == 0) {
+		rc = regulator_enable(vreg->reg);
+		if (!rc)
+			vreg->refcnt++;
+	} else {
+		rc = 0;
+		if (vreg->refcnt < UINT_MAX)
+			vreg->refcnt++;
+	}
+	mutex_unlock(&vreg->lock);
 
-	if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
-		vreg->refcnt++;
-
-	return vreg->status;
+	return rc;
 }
 EXPORT_SYMBOL(vreg_enable);
 
 int vreg_disable(struct vreg *vreg)
 {
-	unsigned id = vreg->id;
-	int disable = VREG_SWITCH_DISABLE;
+	int rc = 0;
+	if (!vreg)
+		return -ENODEV;
 
-	if (!vreg->refcnt)
-		return 0;
-
-	if (vreg->refcnt == 1)
-		vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &disable);
-
-	if (!vreg->status)
+	mutex_lock(&vreg->lock);
+	if (vreg->refcnt == 0) {
+		pr_warn("%s: unbalanced disables for vreg %s\n",
+				__func__, vreg->name);
+		rc = -EINVAL;
+	} else if (vreg->refcnt == 1) {
+		rc = regulator_disable(vreg->reg);
+		if (!rc)
+			vreg->refcnt--;
+	} else {
+		rc = 0;
 		vreg->refcnt--;
+	}
+	mutex_unlock(&vreg->lock);
 
-	return vreg->status;
+	return rc;
 }
 EXPORT_SYMBOL(vreg_disable);
 
 int vreg_set_level(struct vreg *vreg, unsigned mv)
 {
-	unsigned id = vreg->id;
+	unsigned uv;
+	int rc;
 
-	vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
-	return vreg->status;
+	if (!vreg)
+		return -EINVAL;
+
+	if (mv > (UINT_MAX / 1000))
+		return -ERANGE;
+
+	uv = mv * 1000;
+
+	mutex_lock(&vreg->lock);
+	rc = regulator_set_voltage(vreg->reg, uv, uv);
+	if (!rc)
+		vreg->mv = mv;
+	mutex_unlock(&vreg->lock);
+
+	return rc;
 }
 EXPORT_SYMBOL(vreg_set_level);
 
 #if defined(CONFIG_DEBUG_FS)
 
-static int vreg_debug_set(void *data, u64 val)
-{
-	struct vreg *vreg = data;
-	switch (val) {
-	case 0:
-		vreg_disable(vreg);
-		break;
-	case 1:
-		vreg_enable(vreg);
-		break;
-	default:
-		vreg_set_level(vreg, val);
-		break;
-	}
-	return 0;
-}
-
-static int vreg_debug_get(void *data, u64 *val)
+static int vreg_debug_enabled_set(void *data, u64 val)
 {
 	struct vreg *vreg = data;
 
-	if (!vreg->status)
-		*val = 0;
+	if (val == 0)
+		return vreg_disable(vreg);
+	else if (val == 1)
+		return vreg_enable(vreg);
 	else
-		*val = 1;
-
-	return 0;
+		return -EINVAL;
 }
 
-static int vreg_debug_count_set(void *data, u64 val)
-{
-	struct vreg *vreg = data;
-	if (val > UINT_MAX)
-		val = UINT_MAX;
-	vreg->refcnt = val;
-	return 0;
-}
-
-static int vreg_debug_count_get(void *data, u64 *val)
+static int vreg_debug_enabled_get(void *data, u64 *val)
 {
 	struct vreg *vreg = data;
 
@@ -208,33 +227,97 @@
 	return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
-DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
-			vreg_debug_count_set, "%llu\n");
-
-static int __init vreg_debug_init(void)
+static int vreg_debug_voltage_set(void *data, u64 val)
 {
-	struct dentry *dent;
-	int n;
-	char name[32];
-	const char *refcnt_name = "_refcnt";
+	struct vreg *vreg = data;
+	return vreg_set_level(vreg, val);
+}
 
-	dent = debugfs_create_dir("vreg", 0);
-	if (IS_ERR(dent))
-		return 0;
+static int vreg_debug_voltage_get(void *data, u64 *val)
+{
+	struct vreg *vreg = data;
+	*val = vreg->mv;
+	return 0;
+}
 
-	for (n = 0; n < ARRAY_SIZE(vregs); n++) {
-		(void) debugfs_create_file(vregs[n].name, 0644,
-					   dent, vregs + n, &vreg_fops);
+DEFINE_SIMPLE_ATTRIBUTE(vreg_debug_enabled, vreg_debug_enabled_get,
+		vreg_debug_enabled_set, "%llu");
+DEFINE_SIMPLE_ATTRIBUTE(vreg_debug_voltage, vreg_debug_voltage_get,
+		vreg_debug_voltage_set, "%llu");
 
-		strlcpy(name, vregs[n].name, sizeof(name));
-		strlcat(name, refcnt_name, sizeof(name));
-		(void) debugfs_create_file(name, 0644,
-					   dent, vregs + n, &vreg_count_fops);
+static struct dentry *root;
+
+static void vreg_add_debugfs(struct vreg *vreg)
+{
+	struct dentry *dir;
+
+	if (!root)
+		return;
+
+	dir = debugfs_create_dir(vreg->name, root);
+
+	if (IS_ERR_OR_NULL(dir))
+		goto err;
+
+	if (IS_ERR_OR_NULL(debugfs_create_file("enabled", 0644,	dir, vreg,
+					&vreg_debug_enabled)))
+		goto destroy;
+
+	if (IS_ERR_OR_NULL(debugfs_create_file("voltage", 0644, dir, vreg,
+					&vreg_debug_voltage)))
+		goto destroy;
+
+	return;
+
+destroy:
+	debugfs_remove_recursive(dir);
+err:
+	pr_warn("%s: could not create debugfs for vreg %s\n",
+			__func__, vreg->name);
+}
+
+static int __devinit vreg_debug_init(void)
+{
+	root = debugfs_create_dir("vreg", NULL);
+
+	if (IS_ERR_OR_NULL(root)) {
+		pr_debug("%s: error initializing debugfs: %ld - "
+				"disabling debugfs\n",
+				__func__, root ? PTR_ERR(root) : 0);
+		root = NULL;
 	}
 
 	return 0;
 }
-
-device_initcall(vreg_debug_init);
+static void __devexit vreg_debug_exit(void)
+{
+	if (root)
+		debugfs_remove_recursive(root);
+	root = NULL;
+}
+#else
+static inline int __init vreg_debug_init(void) { return 0; }
+static inline void __exit vreg_debug_exit(void) { return 0; }
 #endif
+
+static int __init vreg_init(void)
+{
+	return vreg_debug_init();
+}
+module_init(vreg_init);
+
+static void __exit vreg_exit(void)
+{
+	struct vreg *vreg, *next;
+	vreg_debug_exit();
+
+	mutex_lock(&vreg_lock);
+	list_for_each_entry_safe(vreg, next, &vreg_list, list)
+		vreg_destroy(vreg);
+	mutex_unlock(&vreg_lock);
+}
+module_exit(vreg_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("vreg.c regulator shim");
+MODULE_VERSION("1.0");
diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c
index c9e32de..ccd4918 100644
--- a/arch/arm/mach-shark/leds.c
+++ b/arch/arm/mach-shark/leds.c
@@ -36,7 +36,7 @@
 static short hw_led_state;
 static short saved_state;
 
-static DEFINE_SPINLOCK(leds_lock);
+static DEFINE_RAW_SPINLOCK(leds_lock);
 
 short sequoia_read(int addr) {
   outw(addr,0x24);
@@ -52,7 +52,7 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&leds_lock, flags);
+	raw_spin_lock_irqsave(&leds_lock, flags);
 
 	hw_led_state = sequoia_read(0x09);
 
@@ -144,7 +144,7 @@
 	if  (led_state & LED_STATE_ENABLED)
 		sequoia_write(hw_led_state,0x09);
 
-	spin_unlock_irqrestore(&leds_lock, flags);
+	raw_spin_unlock_irqrestore(&leds_lock, flags);
 }
 
 static int __init leds_init(void)
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 7aacb84..bc5ffce 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -29,7 +29,8 @@
 static void __iomem *l2x0_base;
 static uint32_t aux_ctrl_save;
 static uint32_t data_latency_ctrl;
-static DEFINE_SPINLOCK(l2x0_lock);
+static DEFINE_RAW_SPINLOCK(l2x0_lock);
+
 static uint32_t l2x0_way_mask;	/* Bitmask of active ways */
 static uint32_t l2x0_size;
 static u32 l2x0_cache_id;
@@ -126,7 +127,11 @@
 
 void l2x0_cache_sync(void)
 {
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	cache_sync();
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 #ifdef CONFIG_PL310_ERRATA_727915
@@ -167,9 +172,9 @@
 #endif
 
 	/* clean all ways */
-	spin_lock_irqsave(&l2x0_lock, flags);
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	__l2x0_flush_all();
-	spin_unlock_irqrestore(&l2x0_lock, flags);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_clean_all(void)
@@ -184,13 +189,13 @@
 #endif
 
 	/* clean all ways */
-	spin_lock_irqsave(&l2x0_lock, flags);
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	debug_writel(0x03);
 	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
 	cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
 	cache_sync();
 	debug_writel(0x00);
-	spin_unlock_irqrestore(&l2x0_lock, flags);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_inv_all(void)
@@ -198,13 +203,13 @@
 	unsigned long flags;
 
 	/* invalidate all ways */
-	spin_lock_irqsave(&l2x0_lock, flags);
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	/* Invalidating when L2 is enabled is a nono */
 	BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1);
 	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
 	cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
 	cache_sync();
-	spin_unlock_irqrestore(&l2x0_lock, flags);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_inv_range(unsigned long start, unsigned long end)
@@ -212,7 +217,7 @@
 	void __iomem *base = l2x0_base;
 	unsigned long flags;
 
-	spin_lock_irqsave(&l2x0_lock, flags);
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	if (start & (CACHE_LINE_SIZE - 1)) {
 		start &= ~(CACHE_LINE_SIZE - 1);
 		debug_writel(0x03);
@@ -237,13 +242,13 @@
 		}
 
 		if (blk_end < end) {
-			spin_unlock_irqrestore(&l2x0_lock, flags);
-			spin_lock_irqsave(&l2x0_lock, flags);
+			raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+			raw_spin_lock_irqsave(&l2x0_lock, flags);
 		}
 	}
 	cache_wait(base + L2X0_INV_LINE_PA, 1);
 	cache_sync();
-	spin_unlock_irqrestore(&l2x0_lock, flags);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_inv_range_atomic(unsigned long start, unsigned long end)
@@ -277,7 +282,7 @@
 		return;
 	}
 
-	spin_lock_irqsave(&l2x0_lock, flags);
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	start &= ~(CACHE_LINE_SIZE - 1);
 	while (start < end) {
 		unsigned long blk_end = start + min(end - start, 4096UL);
@@ -288,13 +293,13 @@
 		}
 
 		if (blk_end < end) {
-			spin_unlock_irqrestore(&l2x0_lock, flags);
-			spin_lock_irqsave(&l2x0_lock, flags);
+			raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+			raw_spin_lock_irqsave(&l2x0_lock, flags);
 		}
 	}
 	cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
 	cache_sync();
-	spin_unlock_irqrestore(&l2x0_lock, flags);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static void l2x0_clean_range_atomic(unsigned long start, unsigned long end)
@@ -318,7 +323,7 @@
 		return;
 	}
 
-	spin_lock_irqsave(&l2x0_lock, flags);
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	start &= ~(CACHE_LINE_SIZE - 1);
 	while (start < end) {
 		unsigned long blk_end = start + min(end - start, 4096UL);
@@ -331,13 +336,13 @@
 		debug_writel(0x00);
 
 		if (blk_end < end) {
-			spin_unlock_irqrestore(&l2x0_lock, flags);
-			spin_lock_irqsave(&l2x0_lock, flags);
+			raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+			raw_spin_lock_irqsave(&l2x0_lock, flags);
 		}
 	}
 	cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
 	cache_sync();
-	spin_unlock_irqrestore(&l2x0_lock, flags);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 void l2x0_flush_range_atomic(unsigned long start, unsigned long end)
@@ -355,11 +360,11 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&l2x0_lock, flags);
+	raw_spin_lock_irqsave(&l2x0_lock, flags);
 	__l2x0_flush_all();
 	writel_relaxed(0, l2x0_base + L2X0_CTRL);
 	dsb();
-	spin_unlock_irqrestore(&l2x0_lock, flags);
+	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index b0ee9ba..93aac06 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -16,7 +16,7 @@
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
 
-static DEFINE_SPINLOCK(cpu_asid_lock);
+static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
 unsigned int cpu_last_asid = ASID_FIRST_VERSION;
 #ifdef CONFIG_SMP
 DEFINE_PER_CPU(struct mm_struct *, current_mm);
@@ -31,7 +31,7 @@
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
 	mm->context.id = 0;
-	spin_lock_init(&mm->context.id_lock);
+	raw_spin_lock_init(&mm->context.id_lock);
 }
 
 static void flush_context(void)
@@ -58,7 +58,7 @@
 	 * the broadcast. This function is also called via IPI so the
 	 * mm->context.id_lock has to be IRQ-safe.
 	 */
-	spin_lock_irqsave(&mm->context.id_lock, flags);
+	raw_spin_lock_irqsave(&mm->context.id_lock, flags);
 	if (likely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) {
 		/*
 		 * Old version of ASID found. Set the new one and
@@ -67,7 +67,7 @@
 		mm->context.id = asid;
 		cpumask_clear(mm_cpumask(mm));
 	}
-	spin_unlock_irqrestore(&mm->context.id_lock, flags);
+	raw_spin_unlock_irqrestore(&mm->context.id_lock, flags);
 
 	/*
 	 * Set the mm_cpumask(mm) bit for the current CPU.
@@ -117,7 +117,7 @@
 {
 	unsigned int asid;
 
-	spin_lock(&cpu_asid_lock);
+	raw_spin_lock(&cpu_asid_lock);
 #ifdef CONFIG_SMP
 	/*
 	 * Check the ASID again, in case the change was broadcast from
@@ -125,7 +125,7 @@
 	 */
 	if (unlikely(((mm->context.id ^ cpu_last_asid) >> ASID_BITS) == 0)) {
 		cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
-		spin_unlock(&cpu_asid_lock);
+		raw_spin_unlock(&cpu_asid_lock);
 		return;
 	}
 #endif
@@ -153,5 +153,5 @@
 	}
 
 	set_mm_context(mm, asid);
-	spin_unlock(&cpu_asid_lock);
+	raw_spin_unlock(&cpu_asid_lock);
 }
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index b806151..7d0a8c2 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -30,7 +30,7 @@
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
 				  L_PTE_MT_MINICACHE)
 
-static DEFINE_SPINLOCK(minicache_lock);
+static DEFINE_RAW_SPINLOCK(minicache_lock);
 
 /*
  * ARMv4 mini-dcache optimised copy_user_highpage
@@ -76,14 +76,14 @@
 	if (!test_and_set_bit(PG_dcache_clean, &from->flags))
 		__flush_dcache_page(page_mapping(from), from);
 
-	spin_lock(&minicache_lock);
+	raw_spin_lock(&minicache_lock);
 
 	set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0);
 	flush_tlb_kernel_page(0xffff8000);
 
 	mc_copy_user_page((void *)0xffff8000, kto);
 
-	spin_unlock(&minicache_lock);
+	raw_spin_unlock(&minicache_lock);
 
 	kunmap_atomic(kto, KM_USER1);
 }
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index bdba6c6..b2a8f9c 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -27,7 +27,7 @@
 #define from_address	(0xffff8000)
 #define to_address	(0xffffc000)
 
-static DEFINE_SPINLOCK(v6_lock);
+static DEFINE_RAW_SPINLOCK(v6_lock);
 
 /*
  * Copy the user page.  No aliasing to deal with so we can just
@@ -89,7 +89,7 @@
 	 * Now copy the page using the same cache colour as the
 	 * pages ultimate destination.
 	 */
-	spin_lock(&v6_lock);
+	raw_spin_lock(&v6_lock);
 
 	set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0);
 	set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0);
@@ -102,7 +102,7 @@
 
 	copy_page((void *)kto, (void *)kfrom);
 
-	spin_unlock(&v6_lock);
+	raw_spin_unlock(&v6_lock);
 }
 
 /*
@@ -122,13 +122,13 @@
 	 * Now clear the page using the same cache colour as
 	 * the pages ultimate destination.
 	 */
-	spin_lock(&v6_lock);
+	raw_spin_lock(&v6_lock);
 
 	set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0);
 	flush_tlb_kernel_page(to);
 	clear_page((void *)to);
 
-	spin_unlock(&v6_lock);
+	raw_spin_unlock(&v6_lock);
 }
 
 struct cpu_user_fns v6_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 649bbcd..610c24c 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -32,7 +32,7 @@
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
 				  L_PTE_MT_MINICACHE)
 
-static DEFINE_SPINLOCK(minicache_lock);
+static DEFINE_RAW_SPINLOCK(minicache_lock);
 
 /*
  * XScale mini-dcache optimised copy_user_highpage
@@ -98,14 +98,14 @@
 	if (!test_and_set_bit(PG_dcache_clean, &from->flags))
 		__flush_dcache_page(page_mapping(from), from);
 
-	spin_lock(&minicache_lock);
+	raw_spin_lock(&minicache_lock);
 
 	set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0);
 	flush_tlb_kernel_page(COPYPAGE_MINICACHE);
 
 	mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
 
-	spin_unlock(&minicache_lock);
+	raw_spin_unlock(&minicache_lock);
 
 	kunmap_atomic(kto, KM_USER1);
 }
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 5739a34..e5e3486 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -637,6 +637,9 @@
 	extern u32 dtcm_end;
 	extern u32 itcm_end;
 #endif
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+	struct zone *zone;
+#endif
 
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 
@@ -682,6 +685,14 @@
 #endif
 	}
 
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+	for_each_zone(zone) {
+		if (zone_idx(zone) == ZONE_MOVABLE)
+			total_unmovable_pages = totalram_pages -
+							zone->spanned_pages;
+	}
+#endif
+
 	/*
 	 * Since our memory may not be contiguous, calculate the
 	 * real number of pages we have in this system
@@ -784,6 +795,7 @@
 
 void free_initmem(void)
 {
+	unsigned long reclaimed_initmem;
 #ifdef CONFIG_HAVE_TCM
 	extern char __tcm_start, __tcm_end;
 
@@ -792,10 +804,15 @@
 				    "TCM link");
 #endif
 
-	if (!machine_is_integrator() && !machine_is_cintegrator())
-		totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)),
+	if (!machine_is_integrator() && !machine_is_cintegrator()) {
+		reclaimed_initmem = free_area(__phys_to_pfn(__pa(__init_begin)),
 					    __phys_to_pfn(__pa(__init_end)),
 					    "init");
+		totalram_pages += reclaimed_initmem;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+		total_unmovable_pages += reclaimed_initmem;
+#endif
+	}
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
@@ -831,10 +848,16 @@
 
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	if (!keep_initrd)
-		totalram_pages += free_area(__phys_to_pfn(__pa(start)),
+	unsigned long reclaimed_initrd_mem;
+	if (!keep_initrd) {
+		reclaimed_initrd_mem = free_area(__phys_to_pfn(__pa(start)),
 					    __phys_to_pfn(__pa(end)),
 					    "initrd");
+		totalram_pages += reclaimed_initrd_mem;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+		total_unmovable_pages += reclaimed_initrd_mem;
+#endif
+	}
 }
 
 static int __init keepinitrd_setup(char *__unused)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 84a7e5c..0f79b76 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1124,6 +1124,20 @@
 }
 #endif
 
+void mem_text_write_kernel_word(unsigned long *addr, unsigned long word)
+{
+	unsigned long flags;
+
+	mem_text_writeable_spinlock(&flags);
+	mem_text_address_writeable((unsigned long)addr);
+	*addr = word;
+	flush_icache_range((unsigned long)addr,
+			   ((unsigned long)addr + sizeof(long)));
+	mem_text_address_restore();
+	mem_text_writeable_spinunlock(&flags);
+}
+EXPORT_SYMBOL(mem_text_write_kernel_word);
+
 static void __init map_lowmem(void)
 {
 	struct memblock_region *reg;
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 46729ee..5943005 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -219,7 +219,11 @@
 	 *   NOS = PRRR[24+n] = 1	- not outer shareable
 	 */
 .equ	PRRR,	0xff0a81a8
+#if defined (CONFIG_ARCH_MSM_SCORPIONMP)
+.equ	NMRR,	0x40e080e0
+#else
 .equ	NMRR,	0x40e040e0
+#endif
 
 /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
 .globl	cpu_v7_suspend_size
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index e7fc95c..d25fabf 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -629,7 +629,9 @@
 			if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
 				elf_hwcap |= HWCAP_NEON;
 #endif
-			if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
+
+			if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000 ||
+			    (read_cpuid_id() & 0xff00fc00) == 0x51000400)
 				elf_hwcap |= HWCAP_VFPv4;
 		}
 	}
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 40b9575..41bbd3a 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -37,6 +37,7 @@
 	wait_queue_head_t queue;  /* Holding pen for processes pending lock */
 	struct file *file;        /* File structure for exported lock */
 	int state;                /* Current state of the lock */
+	struct kref refcount;
 };
 
 struct genlock_handle {
@@ -47,6 +48,14 @@
 				     taken */
 };
 
+static void genlock_destroy(struct kref *kref)
+{
+	struct genlock *lock = container_of(kref, struct genlock,
+			refcount);
+
+	kfree(lock);
+}
+
 /*
  * Release the genlock object. Called when all the references to
  * the genlock file descriptor are released
@@ -54,7 +63,6 @@
 
 static int genlock_release(struct inode *inodep, struct file *file)
 {
-	kfree(file->private_data);
 	return 0;
 }
 
@@ -96,6 +104,7 @@
 
 	/* Attach the new lock to the handle */
 	handle->lock = lock;
+	kref_init(&lock->refcount);
 
 	return lock;
 }
@@ -131,6 +140,7 @@
 struct genlock *genlock_attach_lock(struct genlock_handle *handle, int fd)
 {
 	struct file *file;
+	struct genlock *lock;
 
 	if (handle->lock != NULL)
 		return ERR_PTR(-EINVAL);
@@ -139,9 +149,17 @@
 	if (file == NULL)
 		return ERR_PTR(-EBADF);
 
-	handle->lock = file->private_data;
+	lock = file->private_data;
 
-	return handle->lock;
+	fput(file);
+
+	if (lock == NULL)
+		return ERR_PTR(-EINVAL);
+
+	handle->lock = lock;
+	kref_get(&lock->refcount);
+
+	return lock;
 }
 EXPORT_SYMBOL(genlock_attach_lock);
 
@@ -418,7 +436,7 @@
 	}
 	spin_unlock_irqrestore(&handle->lock->lock, flags);
 
-	fput(handle->lock->file);
+	kref_put(&handle->lock->refcount, genlock_destroy);
 	handle->lock = NULL;
 	handle->active = 0;
 }
@@ -575,7 +593,8 @@
 {
 	struct genlock_handle *handle = file->private_data;
 
-	genlock_put_handle(handle);
+	genlock_release_lock(handle);
+	kfree(handle);
 
 	return 0;
 }
diff --git a/drivers/bluetooth/hci_smd.c b/drivers/bluetooth/hci_smd.c
index 118bbb3..a321849 100644
--- a/drivers/bluetooth/hci_smd.c
+++ b/drivers/bluetooth/hci_smd.c
@@ -140,20 +140,20 @@
 	wake_lock(&hs.wake_lock_rx);
 
 	len = smd_read_avail(hsmd->data_channel);
-	if (len <= 0) {
-		BT_ERR("Nothing to read from SMD channel\n");
+	if (len > HCI_MAX_FRAME_SIZE) {
+		BT_ERR("Frame larger than the allowed size");
 		goto out_data;
 	}
 	while (len > 0) {
 		skb = bt_skb_alloc(len, GFP_ATOMIC);
 		if (!skb) {
-			BT_ERR("Error in allocating  socket buffer\n");
+			BT_ERR("Error in allocating  socket buffer");
 			goto out_data;
 		}
 
 		buf = kmalloc(len, GFP_ATOMIC);
 		if (!buf)  {
-			BT_ERR("Error in allocating  buffer\n");
+			BT_ERR("Error in allocating  buffer");
 			rc = -ENOMEM;
 			goto out_data;
 		}
@@ -188,7 +188,7 @@
 		 * Start the timer to monitor whether the Rx queue is
 		 * empty for releasing the Rx wake lock
 		 */
-		BT_DBG("Rx Timer is starting\n");
+		BT_DBG("Rx Timer is starting");
 		mod_timer(&hsmd->rx_q_timer,
 				jiffies + msecs_to_jiffies(RX_Q_MONITOR));
 	}
@@ -214,20 +214,17 @@
 	if (len > HCI_MAX_FRAME_SIZE) {
 		BT_ERR("Frame larger than the allowed size");
 		goto out_event;
-	} else if (len <= 0) {
-		BT_ERR("Nothing to read from SMD channel\n");
-		goto out_event;
 	}
 
 	while (len > 0) {
 		skb = bt_skb_alloc(len, GFP_ATOMIC);
 		if (!skb) {
-			BT_ERR("Error in allocating  socket buffer\n");
+			BT_ERR("Error in allocating  socket buffer");
 			goto out_event;
 		}
 		buf = kmalloc(len, GFP_ATOMIC);
 		if (!buf) {
-			BT_ERR("Error in allocating  buffer\n");
+			BT_ERR("Error in allocating  buffer");
 			rc = -ENOMEM;
 			goto out_event;
 		}
@@ -261,7 +258,7 @@
 		 * Start the timer to monitor whether the Rx queue is
 		 * empty for releasing the Rx wake lock
 		 */
-		BT_DBG("Rx Timer is starting\n");
+		BT_DBG("Rx Timer is starting");
 		mod_timer(&hsmd->rx_q_timer,
 				jiffies + msecs_to_jiffies(RX_Q_MONITOR));
 	}
@@ -308,7 +305,7 @@
 		}
 		break;
 	default:
-		BT_ERR("Uknown packet type\n");
+		BT_ERR("Uknown packet type");
 		ret = -ENODEV;
 		break;
 	}
@@ -322,6 +319,8 @@
 static void hci_smd_notify_event(void *data, unsigned int event)
 {
 	struct hci_dev *hdev = hs.hdev;
+	struct hci_smd_data *hsmd = &hs;
+	int len = 0;
 
 	if (!hdev) {
 		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
@@ -330,12 +329,19 @@
 
 	switch (event) {
 	case SMD_EVENT_DATA:
-		tasklet_hi_schedule(&hs.hci_event_task);
+		len = smd_read_avail(hsmd->event_channel);
+		if (len > 0)
+			tasklet_hi_schedule(&hs.hci_event_task);
+		else if (len < 0)
+			BT_ERR("Failed to read event from smd %d", len);
+
 		break;
 	case SMD_EVENT_OPEN:
+		BT_INFO("opening HCI-SMD channel :%s", EVENT_CHANNEL);
 		hci_smd_open(hdev);
 		break;
 	case SMD_EVENT_CLOSE:
+		BT_INFO("Closing HCI-SMD channel :%s", EVENT_CHANNEL);
 		hci_smd_close(hdev);
 		break;
 	default:
@@ -346,6 +352,9 @@
 static void hci_smd_notify_data(void *data, unsigned int event)
 {
 	struct hci_dev *hdev = hs.hdev;
+	struct hci_smd_data *hsmd = &hs;
+	int len = 0;
+
 	if (!hdev) {
 		BT_ERR("HCI device (hdev=NULL)");
 		return;
@@ -353,12 +362,18 @@
 
 	switch (event) {
 	case SMD_EVENT_DATA:
-		tasklet_hi_schedule(&hs.hci_data_task);
+		len = smd_read_avail(hsmd->data_channel);
+		if (len > 0)
+			tasklet_hi_schedule(&hs.hci_data_task);
+		else if (len < 0)
+			BT_ERR("Failed to read data from smd %d", len);
 		break;
 	case SMD_EVENT_OPEN:
+		BT_INFO("opening HCI-SMD channel :%s", DATA_CHANNEL);
 		hci_smd_open(hdev);
 		break;
 	case SMD_EVENT_CLOSE:
+		BT_INFO("Closing HCI-SMD channel :%s", DATA_CHANNEL);
 		hci_smd_close(hdev);
 		break;
 	default:
@@ -419,7 +434,7 @@
 	rc = smd_named_open_on_edge(DATA_CHANNEL, SMD_APPS_WCNSS,
 			&hsmd->data_channel, hdev, hci_smd_notify_data);
 	if (rc < 0) {
-		BT_ERR("Failed to open the Data channel\n");
+		BT_ERR("Failed to open the Data channel");
 		hci_free_dev(hdev);
 		return -ENODEV;
 	}
diff --git a/drivers/gpu/ion/Makefile b/drivers/gpu/ion/Makefile
index c0a47d8..3911950 100644
--- a/drivers/gpu/ion/Makefile
+++ b/drivers/gpu/ion/Makefile
@@ -1,3 +1,3 @@
-obj-$(CONFIG_ION) +=	ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o
+obj-$(CONFIG_ION) +=	ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o ion_iommu_heap.o
 obj-$(CONFIG_ION_TEGRA) += tegra/
 obj-$(CONFIG_ION_MSM) += msm/
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 48dc9c0..e659df5 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -30,6 +30,7 @@
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
 
+#include <mach/iommu_domains.h>
 #include "ion_priv.h"
 #define DEBUG
 
@@ -102,8 +103,27 @@
 	unsigned int kmap_cnt;
 	unsigned int dmap_cnt;
 	unsigned int usermap_cnt;
+	unsigned int iommu_map_cnt;
 };
 
+static int ion_validate_buffer_flags(struct ion_buffer *buffer,
+					unsigned long flags)
+{
+	if (buffer->kmap_cnt || buffer->dmap_cnt || buffer->umap_cnt ||
+		buffer->iommu_map_cnt) {
+		if (buffer->flags != flags) {
+			pr_err("%s: buffer was already mapped with flags %lx,"
+				" cannot map with flags %lx\n", __func__,
+				buffer->flags, flags);
+			return 1;
+		}
+
+	} else {
+		buffer->flags = flags;
+	}
+	return 0;
+}
+
 /* this function should only be called while dev->lock is held */
 static void ion_buffer_add(struct ion_device *dev,
 			   struct ion_buffer *buffer)
@@ -130,6 +150,61 @@
 	rb_insert_color(&buffer->node, &dev->buffers);
 }
 
+void ion_iommu_add(struct ion_buffer *buffer,
+			  struct ion_iommu_map *iommu)
+{
+	struct rb_node **p = &buffer->iommu_maps.rb_node;
+	struct rb_node *parent = NULL;
+	struct ion_iommu_map *entry;
+
+	while (*p) {
+		parent = *p;
+		entry = rb_entry(parent, struct ion_iommu_map, node);
+
+		if (iommu->key < entry->key) {
+			p = &(*p)->rb_left;
+		} else if (iommu->key > entry->key) {
+			p = &(*p)->rb_right;
+		} else {
+			pr_err("%s: buffer %p already has mapping for domain %d"
+				" and partition %d\n", __func__,
+				buffer,
+				iommu_map_domain(iommu),
+				iommu_map_partition(iommu));
+			BUG();
+		}
+	}
+
+	rb_link_node(&iommu->node, parent, p);
+	rb_insert_color(&iommu->node, &buffer->iommu_maps);
+
+}
+
+static struct ion_iommu_map *ion_iommu_lookup(struct ion_buffer *buffer,
+						unsigned int domain_no,
+						unsigned int partition_no)
+{
+	struct rb_node **p = &buffer->iommu_maps.rb_node;
+	struct rb_node *parent = NULL;
+	struct ion_iommu_map *entry;
+	uint64_t key = domain_no;
+	key = key << 32 | partition_no;
+
+	while (*p) {
+		parent = *p;
+		entry = rb_entry(parent, struct ion_iommu_map, node);
+
+		if (key < entry->key)
+			p = &(*p)->rb_left;
+		else if (key > entry->key)
+			p = &(*p)->rb_right;
+		else
+			return entry;
+	}
+
+	return NULL;
+}
+
 /* this function should only be called while dev->lock is held */
 static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
 				     struct ion_device *dev,
@@ -433,17 +508,9 @@
 		return ERR_PTR(-ENODEV);
 	}
 
-	if (buffer->kmap_cnt || buffer->dmap_cnt || buffer->umap_cnt) {
-		if (buffer->flags != flags) {
-			pr_err("%s: buffer was already mapped with flags %lx,"
-				" cannot map with flags %lx\n", __func__,
-				buffer->flags, flags);
+	if (ion_validate_buffer_flags(buffer, flags)) {
 			vaddr = ERR_PTR(-EEXIST);
 			goto out;
-		}
-
-	} else {
-		buffer->flags = flags;
 	}
 
 	if (_ion_map(&buffer->kmap_cnt, &handle->kmap_cnt)) {
@@ -462,6 +529,179 @@
 	return vaddr;
 }
 
+int __ion_iommu_map(struct ion_buffer *buffer,
+		int domain_num, int partition_num, unsigned long align,
+		unsigned long iova_length, unsigned long flags,
+		unsigned long *iova)
+{
+	struct ion_iommu_map *data;
+	int ret;
+
+	data = kmalloc(sizeof(*data), GFP_ATOMIC);
+
+	if (!data)
+		return -ENOMEM;
+
+	data->buffer = buffer;
+	iommu_map_domain(data) = domain_num;
+	iommu_map_partition(data) = partition_num;
+
+	ret = buffer->heap->ops->map_iommu(buffer, data,
+						domain_num,
+						partition_num,
+						align,
+						iova_length,
+						flags);
+
+	if (ret)
+		goto out;
+
+	kref_init(&data->ref);
+	*iova = data->iova_addr;
+
+	ion_iommu_add(buffer, data);
+
+	return 0;
+
+out:
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				buffer->size);
+	kfree(data);
+	return ret;
+}
+
+int ion_map_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num, unsigned long align,
+			unsigned long iova_length, unsigned long *iova,
+			unsigned long *buffer_size,
+			unsigned long flags)
+{
+	struct ion_buffer *buffer;
+	struct ion_iommu_map *iommu_map;
+	int ret = 0;
+
+	mutex_lock(&client->lock);
+	if (!ion_handle_validate(client, handle)) {
+		pr_err("%s: invalid handle passed to map_kernel.\n",
+		       __func__);
+		mutex_unlock(&client->lock);
+		return -EINVAL;
+	}
+
+	buffer = handle->buffer;
+	mutex_lock(&buffer->lock);
+
+	if (!handle->buffer->heap->ops->map_iommu) {
+		pr_err("%s: map_iommu is not implemented by this heap.\n",
+		       __func__);
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (ion_validate_buffer_flags(buffer, flags)) {
+		ret = -EEXIST;
+		goto out;
+	}
+
+	/*
+	 * If clients don't want a custom iova length, just use whatever
+	 * the buffer size is
+	 */
+	if (!iova_length)
+		iova_length = buffer->size;
+
+	if (buffer->size > iova_length) {
+		pr_debug("%s: iova length %lx is not at least buffer size"
+			" %x\n", __func__, iova_length, buffer->size);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (buffer->size & ~PAGE_MASK) {
+		pr_debug("%s: buffer size %x is not aligned to %lx", __func__,
+			buffer->size, PAGE_SIZE);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (iova_length & ~PAGE_MASK) {
+		pr_debug("%s: iova_length %lx is not aligned to %lx", __func__,
+			iova_length, PAGE_SIZE);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	iommu_map = ion_iommu_lookup(buffer, domain_num, partition_num);
+	if (_ion_map(&buffer->iommu_map_cnt, &handle->iommu_map_cnt) ||
+		!iommu_map) {
+		ret = __ion_iommu_map(buffer, domain_num, partition_num, align,
+					iova_length, flags, iova);
+		if (ret < 0)
+			_ion_unmap(&buffer->iommu_map_cnt,
+				   &handle->iommu_map_cnt);
+	} else {
+		if (iommu_map->mapped_size != iova_length) {
+			pr_err("%s: handle %p is already mapped with length"
+				" %x, trying to map with length %lx\n",
+				__func__, handle, iommu_map->mapped_size,
+				iova_length);
+			_ion_unmap(&buffer->iommu_map_cnt,
+				   &handle->iommu_map_cnt);
+			ret = -EINVAL;
+		} else {
+			kref_get(&iommu_map->ref);
+			*iova = iommu_map->iova_addr;
+		}
+	}
+	*buffer_size = buffer->size;
+out:
+	mutex_unlock(&buffer->lock);
+	mutex_unlock(&client->lock);
+	return ret;
+}
+EXPORT_SYMBOL(ion_map_iommu);
+
+static void ion_iommu_release(struct kref *kref)
+{
+	struct ion_iommu_map *map = container_of(kref, struct ion_iommu_map,
+						ref);
+	struct ion_buffer *buffer = map->buffer;
+
+	rb_erase(&map->node, &buffer->iommu_maps);
+	buffer->heap->ops->unmap_iommu(map);
+	kfree(map);
+}
+
+void ion_unmap_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num)
+{
+	struct ion_iommu_map *iommu_map;
+	struct ion_buffer *buffer;
+
+	mutex_lock(&client->lock);
+	buffer = handle->buffer;
+
+	mutex_lock(&buffer->lock);
+
+	iommu_map = ion_iommu_lookup(buffer, domain_num, partition_num);
+
+	if (!iommu_map) {
+		WARN(1, "%s: (%d,%d) was never mapped for %p\n", __func__,
+				domain_num, partition_num, buffer);
+		goto out;
+	}
+
+	_ion_unmap(&buffer->iommu_map_cnt, &handle->iommu_map_cnt);
+	kref_put(&iommu_map->ref, ion_iommu_release);
+
+out:
+	mutex_unlock(&buffer->lock);
+
+	mutex_unlock(&client->lock);
+
+}
+EXPORT_SYMBOL(ion_unmap_iommu);
+
 struct scatterlist *ion_map_dma(struct ion_client *client,
 				struct ion_handle *handle,
 				unsigned long flags)
@@ -487,17 +727,9 @@
 		return ERR_PTR(-ENODEV);
 	}
 
-	if (buffer->kmap_cnt || buffer->dmap_cnt || buffer->umap_cnt) {
-		if (buffer->flags != flags) {
-			pr_err("%s: buffer was already mapped with flags %lx,"
-				" cannot map with flags %lx\n", __func__,
-				buffer->flags, flags);
-			sglist = ERR_PTR(-EEXIST);
-			goto out;
-		}
-
-	} else {
-		buffer->flags = flags;
+	if (ion_validate_buffer_flags(buffer, flags)) {
+		sglist = ERR_PTR(-EEXIST);
+		goto out;
 	}
 
 	if (_ion_map(&buffer->dmap_cnt, &handle->dmap_cnt)) {
@@ -746,7 +978,6 @@
 	struct rb_node **p;
 	struct rb_node *parent = NULL;
 	struct ion_client *entry;
-	char debug_name[64];
 	pid_t pid;
 
 	get_task_struct(current->group_leader);
@@ -816,8 +1047,8 @@
 		rb_insert_color(&client->node, &dev->kernel_clients);
 	}
 
-	snprintf(debug_name, 64, "%u", client->pid);
-	client->debug_root = debugfs_create_file(debug_name, 0664,
+
+	client->debug_root = debugfs_create_file(name, 0664,
 						 dev->debug_root, client,
 						 &debug_client_fops);
 	mutex_unlock(&dev->lock);
@@ -888,14 +1119,33 @@
 }
 EXPORT_SYMBOL(ion_handle_get_flags);
 
+int ion_handle_get_size(struct ion_client *client, struct ion_handle *handle,
+			unsigned long *size)
+{
+	struct ion_buffer *buffer;
+
+	mutex_lock(&client->lock);
+	if (!ion_handle_validate(client, handle)) {
+		pr_err("%s: invalid handle passed to %s.\n",
+		       __func__, __func__);
+		mutex_unlock(&client->lock);
+		return -EINVAL;
+	}
+	buffer = handle->buffer;
+	mutex_lock(&buffer->lock);
+	*size = buffer->size;
+	mutex_unlock(&buffer->lock);
+	mutex_unlock(&client->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(ion_handle_get_size);
+
 static int ion_share_release(struct inode *inode, struct file* file)
 {
 	struct ion_buffer *buffer = file->private_data;
 
 	pr_debug("%s: %d\n", __func__, __LINE__);
-	mutex_lock(&buffer->lock);
-	buffer->umap_cnt--;
-	mutex_unlock(&buffer->lock);
 	/* drop the reference to the buffer -- this prevents the
 	   buffer from going away because the client holding it exited
 	   while it was being passed */
@@ -918,6 +1168,9 @@
 		vma->vm_private_data = NULL;
 		return;
 	}
+	mutex_lock(&buffer->lock);
+	buffer->umap_cnt++;
+	mutex_unlock(&buffer->lock);
 	pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n",
 		 __func__, __LINE__,
 		 atomic_read(&client->ref.refcount),
@@ -936,6 +1189,14 @@
 	if (!handle)
 		return;
 	client = handle->client;
+	mutex_lock(&buffer->lock);
+	buffer->umap_cnt--;
+	mutex_unlock(&buffer->lock);
+
+	if (buffer->heap->ops->unmap_user)
+		buffer->heap->ops->unmap_user(buffer->heap, buffer);
+
+
 	pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n",
 		 __func__, __LINE__,
 		 atomic_read(&client->ref.refcount),
@@ -1001,23 +1262,16 @@
 	}
 
 	mutex_lock(&buffer->lock);
-	if (buffer->kmap_cnt || buffer->dmap_cnt || buffer->umap_cnt) {
-		if (buffer->flags != flags) {
-			pr_err("%s: buffer was already mapped with flags %lx,"
-				" cannot map with flags %lx\n", __func__,
-				buffer->flags, flags);
-			ret = -EEXIST;
-			mutex_unlock(&buffer->lock);
-			goto err1;
-		}
 
-	} else {
-		buffer->flags = flags;
+	if (ion_validate_buffer_flags(buffer, flags)) {
+		ret = -EEXIST;
+		mutex_unlock(&buffer->lock);
+		goto err1;
 	}
+
 	/* now map it to userspace */
 	ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma,
 						flags);
-	buffer->umap_cnt++;
 	mutex_unlock(&buffer->lock);
 	if (ret) {
 		pr_err("%s: failure mapping buffer to userspace\n",
@@ -1242,9 +1496,11 @@
 	struct miscdevice *miscdev = file->private_data;
 	struct ion_device *dev = container_of(miscdev, struct ion_device, dev);
 	struct ion_client *client;
+	char debug_name[64];
 
 	pr_debug("%s: %d\n", __func__, __LINE__);
-	client = ion_client_create(dev, -1, "user");
+	snprintf(debug_name, 64, "%u", task_pid_nr(current->group_leader));
+	client = ion_client_create(dev, -1, debug_name);
 	if (IS_ERR_OR_NULL(client))
 		return PTR_ERR(client);
 	file->private_data = client;
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 71dea89..9cb338a 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -2,6 +2,7 @@
  * drivers/gpu/ion/ion_carveout_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
+ * Copyright (c) 2011, 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
@@ -23,8 +24,10 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/iommu.h>
 #include "ion_priv.h"
 
+#include <mach/iommu_domains.h>
 #include <asm/mach/map.h>
 
 struct ion_carveout_heap {
@@ -33,6 +36,10 @@
 	ion_phys_addr_t base;
 	unsigned long allocated_bytes;
 	unsigned long total_size;
+	void (*request_region)(void *);
+	void (*release_region)(void *);
+	atomic_t map_count;
+	void *bus_id;
 };
 
 ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
@@ -128,6 +135,13 @@
 				   struct ion_buffer *buffer,
 				   unsigned long flags)
 {
+	struct ion_carveout_heap *carveout_heap =
+		container_of(heap, struct ion_carveout_heap, heap);
+
+	if (atomic_inc_return(&carveout_heap->map_count) == 1)
+		if (carveout_heap->request_region)
+			carveout_heap->request_region(carveout_heap->bus_id);
+
 	if (ION_IS_CACHED(flags))
 		return ioremap_cached(buffer->priv_phys, buffer->size);
 	else
@@ -137,26 +151,52 @@
 void ion_carveout_heap_unmap_kernel(struct ion_heap *heap,
 				    struct ion_buffer *buffer)
 {
+	struct ion_carveout_heap *carveout_heap =
+		container_of(heap, struct ion_carveout_heap, heap);
+
 	__arch_iounmap(buffer->vaddr);
 	buffer->vaddr = NULL;
+
+	if (atomic_dec_and_test(&carveout_heap->map_count))
+		if (carveout_heap->release_region)
+			carveout_heap->release_region(carveout_heap->bus_id);
+
 	return;
 }
 
 int ion_carveout_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
 			       struct vm_area_struct *vma, unsigned long flags)
 {
+	struct ion_carveout_heap *carveout_heap =
+		container_of(heap, struct ion_carveout_heap, heap);
+
+	if (atomic_inc_return(&carveout_heap->map_count) == 1)
+		if (carveout_heap->request_region)
+			carveout_heap->request_region(carveout_heap->bus_id);
+
 	if (ION_IS_CACHED(flags))
 		return remap_pfn_range(vma, vma->vm_start,
 			       __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
-			       buffer->size,
+			       vma->vm_end - vma->vm_start,
 			       vma->vm_page_prot);
 	else
 		return remap_pfn_range(vma, vma->vm_start,
 			       __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
-					buffer->size,
+					vma->vm_end - vma->vm_start,
 					pgprot_noncached(vma->vm_page_prot));
 }
 
+void ion_carveout_heap_unmap_user(struct ion_heap *heap,
+				    struct ion_buffer *buffer)
+{
+	struct ion_carveout_heap *carveout_heap =
+		container_of(heap, struct ion_carveout_heap, heap);
+
+	if (atomic_dec_and_test(&carveout_heap->map_count))
+		if (carveout_heap->release_region)
+			carveout_heap->release_region(carveout_heap->bus_id);
+}
+
 int ion_carveout_cache_ops(struct ion_heap *heap, struct ion_buffer *buffer,
 			void *vaddr, unsigned int offset, unsigned int length,
 			unsigned int cmd)
@@ -199,18 +239,123 @@
 	return carveout_heap->total_size;
 }
 
+int ion_carveout_heap_map_iommu(struct ion_buffer *buffer,
+					struct ion_iommu_map *data,
+					unsigned int domain_num,
+					unsigned int partition_num,
+					unsigned long align,
+					unsigned long iova_length,
+					unsigned long flags)
+{
+	unsigned long temp_phys, temp_iova;
+	struct iommu_domain *domain;
+	int i, ret = 0;
+	unsigned long extra;
+
+	data->mapped_size = iova_length;
+
+	if (!msm_use_iommu()) {
+		data->iova_addr = buffer->priv_phys;
+		return 0;
+	}
+
+	extra = iova_length - buffer->size;
+
+	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align);
+
+	if (!data->iova_addr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out1;
+	}
+
+	temp_iova = data->iova_addr;
+	temp_phys = buffer->priv_phys;
+	for (i = buffer->size; i > 0; i -= SZ_4K, temp_iova += SZ_4K,
+						  temp_phys += SZ_4K) {
+		ret = iommu_map(domain, temp_iova, temp_phys,
+				get_order(SZ_4K),
+				ION_IS_CACHED(flags) ? 1 : 0);
+
+		if (ret) {
+			pr_err("%s: could not map %lx to %lx in domain %p\n",
+				__func__, temp_iova, temp_phys, domain);
+			goto out2;
+		}
+	}
+
+	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
+		goto out2;
+
+	return 0;
+
+
+out2:
+	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+out1:
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+
+out:
+
+	return ret;
+}
+
+void ion_carveout_heap_unmap_iommu(struct ion_iommu_map *data)
+{
+	int i;
+	unsigned long temp_iova;
+	unsigned int domain_num;
+	unsigned int partition_num;
+	struct iommu_domain *domain;
+
+	if (!msm_use_iommu())
+		return;
+
+	domain_num = iommu_map_domain(data);
+	partition_num = iommu_map_partition(data);
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+		return;
+	}
+
+	temp_iova = data->iova_addr;
+	for (i = data->mapped_size; i > 0; i -= SZ_4K, temp_iova += SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+
+	return;
+}
+
 static struct ion_heap_ops carveout_heap_ops = {
 	.allocate = ion_carveout_heap_allocate,
 	.free = ion_carveout_heap_free,
 	.phys = ion_carveout_heap_phys,
 	.map_user = ion_carveout_heap_map_user,
 	.map_kernel = ion_carveout_heap_map_kernel,
+	.unmap_user = ion_carveout_heap_unmap_user,
 	.unmap_kernel = ion_carveout_heap_unmap_kernel,
 	.map_dma = ion_carveout_heap_map_dma,
 	.unmap_dma = ion_carveout_heap_unmap_dma,
 	.cache_op = ion_carveout_cache_ops,
 	.get_allocated = ion_carveout_get_allocated,
 	.get_total = ion_carveout_get_total,
+	.map_iommu = ion_carveout_heap_map_iommu,
+	.unmap_iommu = ion_carveout_heap_unmap_iommu,
 };
 
 struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
@@ -238,6 +383,12 @@
 	carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT;
 	carveout_heap->allocated_bytes = 0;
 	carveout_heap->total_size = heap_data->size;
+	if (heap_data->setup_region)
+		carveout_heap->bus_id = heap_data->setup_region();
+	if (heap_data->request_region)
+		carveout_heap->request_region = heap_data->request_region;
+	if (heap_data->release_region)
+		carveout_heap->release_region = heap_data->release_region;
 
 	return &carveout_heap->heap;
 }
diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c
index 8ce3c19..900f445 100644
--- a/drivers/gpu/ion/ion_heap.c
+++ b/drivers/gpu/ion/ion_heap.c
@@ -32,6 +32,9 @@
 	case ION_HEAP_TYPE_CARVEOUT:
 		heap = ion_carveout_heap_create(heap_data);
 		break;
+	case ION_HEAP_TYPE_IOMMU:
+		heap = ion_iommu_heap_create(heap_data);
+		break;
 	default:
 		pr_err("%s: Invalid heap type %d\n", __func__,
 		       heap_data->type);
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
new file mode 100644
index 0000000..d37a811
--- /dev/null
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2011, 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/err.h>
+#include <linux/io.h>
+#include <linux/ion.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/iommu.h>
+#include <linux/pfn.h>
+#include "ion_priv.h"
+
+#include <asm/mach/map.h>
+#include <asm/page.h>
+#include <mach/iommu_domains.h>
+
+struct ion_iommu_heap {
+	struct ion_heap heap;
+};
+
+struct ion_iommu_priv_data {
+	struct page **pages;
+	int nrpages;
+	unsigned long size;
+};
+
+static int ion_iommu_heap_allocate(struct ion_heap *heap,
+				      struct ion_buffer *buffer,
+				      unsigned long size, unsigned long align,
+				      unsigned long flags)
+{
+	int ret, i;
+	struct ion_iommu_priv_data *data = NULL;
+
+	if (msm_use_iommu()) {
+		data = kmalloc(sizeof(*data), GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+
+		data->size = PFN_ALIGN(size);
+		data->nrpages = data->size >> PAGE_SHIFT;
+		data->pages = kzalloc(sizeof(struct page *)*data->nrpages,
+				GFP_KERNEL);
+		if (!data->pages) {
+			ret = -ENOMEM;
+			goto err1;
+		}
+
+		for (i = 0; i < data->nrpages; i++) {
+			data->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			if (!data->pages[i])
+				goto err2;
+		}
+
+
+		buffer->priv_virt = data;
+		return 0;
+
+	} else {
+		return -ENOMEM;
+	}
+
+
+err2:
+	for (i = 0; i < data->nrpages; i++) {
+		if (data->pages[i])
+			__free_page(data->pages[i]);
+	}
+	kfree(data->pages);
+err1:
+	kfree(data);
+	return ret;
+}
+
+static void ion_iommu_heap_free(struct ion_buffer *buffer)
+{
+	struct ion_iommu_priv_data *data = buffer->priv_virt;
+	int i;
+
+	if (!data)
+		return;
+
+	for (i = 0; i < data->nrpages; i++)
+		__free_page(data->pages[i]);
+
+	kfree(data->pages);
+	kfree(data);
+}
+
+void *ion_iommu_heap_map_kernel(struct ion_heap *heap,
+				   struct ion_buffer *buffer,
+				   unsigned long flags)
+{
+	struct ion_iommu_priv_data *data = buffer->priv_virt;
+	pgprot_t page_prot = PAGE_KERNEL;
+
+	if (!data)
+		return NULL;
+
+	if (!ION_IS_CACHED(flags))
+		page_prot = pgprot_noncached(page_prot);
+
+	buffer->vaddr = vmap(data->pages, data->nrpages, VM_IOREMAP, page_prot);
+
+	return buffer->vaddr;
+}
+
+void ion_iommu_heap_unmap_kernel(struct ion_heap *heap,
+				    struct ion_buffer *buffer)
+{
+	if (!buffer->vaddr)
+		return;
+
+	vunmap(buffer->vaddr);
+	buffer->vaddr = NULL;
+}
+
+int ion_iommu_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
+			       struct vm_area_struct *vma, unsigned long flags)
+{
+	struct ion_iommu_priv_data *data = buffer->priv_virt;
+	int i;
+
+	if (!data)
+		return -EINVAL;
+
+	if (!ION_IS_CACHED(flags))
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	for (i = 0; i < data->nrpages; i++)
+		if (vm_insert_page(vma, vma->vm_start + i * PAGE_SIZE,
+			data->pages[i]))
+			/*
+			 * This will fail the mmap which will
+			 * clean up the vma space properly.
+			 */
+			return -EINVAL;
+
+	return 0;
+}
+
+int ion_iommu_heap_map_iommu(struct ion_buffer *buffer,
+					struct ion_iommu_map *data,
+					unsigned int domain_num,
+					unsigned int partition_num,
+					unsigned long align,
+					unsigned long iova_length,
+					unsigned long flags)
+{
+	unsigned long temp_iova;
+	struct iommu_domain *domain;
+	struct ion_iommu_priv_data *buffer_data = buffer->priv_virt;
+	int i, j, ret = 0;
+	unsigned long extra;
+
+	BUG_ON(!msm_use_iommu());
+
+	data->mapped_size = iova_length;
+	extra = iova_length - buffer->size;
+
+	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align);
+
+	if (!data->iova_addr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out1;
+	}
+
+	temp_iova = data->iova_addr;
+	for (i = buffer->size, j = 0; i > 0; j++, i -= SZ_4K,
+						temp_iova += SZ_4K) {
+		ret = iommu_map(domain, temp_iova,
+				page_to_phys(buffer_data->pages[j]),
+				get_order(SZ_4K),
+				ION_IS_CACHED(flags) ? 1 : 0);
+
+		if (ret) {
+			pr_err("%s: could not map %lx to %x in domain %p\n",
+				__func__, temp_iova,
+				page_to_phys(buffer_data->pages[j]),
+				domain);
+			goto out2;
+		}
+	}
+
+
+	if (extra &&
+		msm_iommu_map_extra
+			(domain, temp_iova, extra, flags) < 0)
+		goto out2;
+
+	return 0;
+
+
+out2:
+	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+out1:
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				buffer->size);
+
+out:
+
+	return ret;
+}
+
+void ion_iommu_heap_unmap_iommu(struct ion_iommu_map *data)
+{
+	int i;
+	unsigned long temp_iova;
+	unsigned int domain_num;
+	unsigned int partition_num;
+	struct iommu_domain *domain;
+
+	BUG_ON(!msm_use_iommu());
+
+	domain_num = iommu_map_domain(data);
+	partition_num = iommu_map_partition(data);
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+		return;
+	}
+
+	temp_iova = data->iova_addr;
+	for (i = data->mapped_size; i > 0; i -= SZ_4K, temp_iova += SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+
+	return;
+}
+
+
+static struct ion_heap_ops iommu_heap_ops = {
+	.allocate = ion_iommu_heap_allocate,
+	.free = ion_iommu_heap_free,
+	.map_user = ion_iommu_heap_map_user,
+	.map_kernel = ion_iommu_heap_map_kernel,
+	.unmap_kernel = ion_iommu_heap_unmap_kernel,
+	.map_iommu = ion_iommu_heap_map_iommu,
+	.unmap_iommu = ion_iommu_heap_unmap_iommu,
+};
+
+struct ion_heap *ion_iommu_heap_create(struct ion_platform_heap *heap_data)
+{
+	struct ion_iommu_heap *iommu_heap;
+
+	iommu_heap = kzalloc(sizeof(struct ion_iommu_heap), GFP_KERNEL);
+	if (!iommu_heap)
+		return ERR_PTR(-ENOMEM);
+
+	iommu_heap->heap.ops = &iommu_heap_ops;
+	iommu_heap->heap.type = ION_HEAP_TYPE_IOMMU;
+
+	return &iommu_heap->heap;
+}
+
+void ion_iommu_heap_destroy(struct ion_heap *heap)
+{
+	struct ion_iommu_heap *iommu_heap =
+	     container_of(heap, struct  ion_iommu_heap, heap);
+
+	kfree(iommu_heap);
+	iommu_heap = NULL;
+}
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 888b599..77b73e2 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -22,6 +22,7 @@
 #include <linux/mutex.h>
 #include <linux/rbtree.h>
 #include <linux/ion.h>
+#include <linux/iommu.h>
 
 struct ion_mapping;
 
@@ -35,6 +36,34 @@
 	void *vaddr;
 };
 
+/**
+ * struct ion_iommu_map - represents a mapping of an ion buffer to an iommu
+ * @iova_addr - iommu virtual address
+ * @node - rb node to exist in the buffer's tree of iommu mappings
+ * @domain_info - contains the partition number and domain number
+ *		domain_info[1] = domain number
+ *		domain_info[0] = partition number
+ * @ref - for reference counting this mapping
+ * @mapped_size - size of the iova space mapped
+ *		(may not be the same as the buffer size)
+ *
+ * Represents a mapping of one ion buffer to a particular iommu domain
+ * and address range. There may exist other mappings of this buffer in
+ * different domains or address ranges. All mappings will have the same
+ * cacheability and security.
+ */
+struct ion_iommu_map {
+	unsigned long iova_addr;
+	struct rb_node node;
+	union {
+		int domain_info[2];
+		uint64_t key;
+	};
+	struct ion_buffer *buffer;
+	struct kref ref;
+	int mapped_size;
+};
+
 struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
 
 /**
@@ -72,6 +101,8 @@
 	int dmap_cnt;
 	struct scatterlist *sglist;
 	int umap_cnt;
+	unsigned int iommu_map_cnt;
+	struct rb_root iommu_maps;
 	int marked;
 };
 
@@ -86,6 +117,7 @@
  * @map_kernel		map memory to the kernel
  * @unmap_kernel	unmap memory to the kernel
  * @map_user		map memory to userspace
+ * @unmap_user		unmap memory to userspace
  */
 struct ion_heap_ops {
 	int (*allocate) (struct ion_heap *heap,
@@ -102,11 +134,21 @@
 	void (*unmap_kernel) (struct ion_heap *heap, struct ion_buffer *buffer);
 	int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer,
 			 struct vm_area_struct *vma, unsigned long flags);
+	void (*unmap_user) (struct ion_heap *mapper, struct ion_buffer *buffer);
 	int (*cache_op)(struct ion_heap *heap, struct ion_buffer *buffer,
 			void *vaddr, unsigned int offset,
 			unsigned int length, unsigned int cmd);
 	unsigned long (*get_allocated)(struct ion_heap *heap);
 	unsigned long (*get_total)(struct ion_heap *heap);
+	int (*map_iommu)(struct ion_buffer *buffer,
+				struct ion_iommu_map *map_data,
+				unsigned int domain_num,
+				unsigned int partition_num,
+				unsigned long align,
+				unsigned long iova_length,
+				unsigned long flags);
+	void (*unmap_iommu)(struct ion_iommu_map *data);
+
 };
 
 /**
@@ -134,6 +176,11 @@
 	const char *name;
 };
 
+
+
+#define iommu_map_domain(__m)		((__m)->domain_info[1])
+#define iommu_map_partition(__m)	((__m)->domain_info[0])
+
 /**
  * ion_device_create - allocates and returns an ion device
  * @custom_ioctl:	arch specific ioctl function if applicable
@@ -175,6 +222,10 @@
 
 struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *);
 void ion_carveout_heap_destroy(struct ion_heap *);
+
+struct ion_heap *ion_iommu_heap_create(struct ion_platform_heap *);
+void ion_iommu_heap_destroy(struct ion_heap *);
+
 /**
  * kernel api to allocate/free from carveout -- used when carveout is
  * used to back an architecture specific custom heap
@@ -183,6 +234,9 @@
 				      unsigned long align);
 void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
 		       unsigned long size);
+
+
+struct ion_heap *msm_get_contiguous_heap(void);
 /**
  * The carveout heap returns physical addresses, since 0 may be a valid
  * physical address, this is used to indicate allocation failed
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index b26d48c..5957658 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -2,6 +2,7 @@
  * drivers/gpu/ion/ion_system_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
+ * Copyright (c) 2011, 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
@@ -20,6 +21,8 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/iommu.h>
+#include <mach/iommu_domains.h>
 #include "ion_priv.h"
 #include <mach/memory.h>
 
@@ -98,6 +101,37 @@
 {
 }
 
+void ion_system_heap_unmap_iommu(struct ion_iommu_map *data)
+{
+	int i;
+	unsigned long temp_iova;
+	unsigned int domain_num;
+	unsigned int partition_num;
+	struct iommu_domain *domain;
+
+	if (!msm_use_iommu())
+		return;
+
+	domain_num = iommu_map_domain(data);
+	partition_num = iommu_map_partition(data);
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		WARN(1, "Could not get domain %d. Corruption?\n", domain_num);
+		return;
+	}
+
+	temp_iova = data->iova_addr;
+	for (i = data->mapped_size; i > 0; i -= SZ_4K, temp_iova += SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+				data->mapped_size);
+
+	return;
+}
+
 int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
 			     struct vm_area_struct *vma, unsigned long flags)
 {
@@ -160,6 +194,77 @@
 	return atomic_read(&system_heap_allocated);
 }
 
+int ion_system_heap_map_iommu(struct ion_buffer *buffer,
+				struct ion_iommu_map *data,
+				unsigned int domain_num,
+				unsigned int partition_num,
+				unsigned long align,
+				unsigned long iova_length,
+				unsigned long flags)
+{
+	int ret, i;
+	unsigned long temp_iova;
+	struct iommu_domain *domain;
+	void *temp_phys;
+	unsigned long extra;
+
+	if (!ION_IS_CACHED(flags))
+		return -EINVAL;
+
+	if (!msm_use_iommu())
+		return -EINVAL;
+
+	data->mapped_size = iova_length;
+	extra = iova_length - buffer->size;
+
+	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align);
+
+	if (!data->iova_addr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out1;
+	}
+
+	temp_iova = data->iova_addr;
+	temp_phys = buffer->vaddr;
+	for (i = buffer->size; i > 0; i -= SZ_4K, temp_iova += SZ_4K,
+						  temp_phys += SZ_4K) {
+		ret = iommu_map(domain, temp_iova,
+			page_to_phys(vmalloc_to_page(temp_phys)),
+			get_order(SZ_4K), ION_IS_CACHED(flags) ? 1 : 0);
+
+		if (ret) {
+			pr_err("%s: could not map %lx to %x in domain %p\n",
+				__func__, temp_iova,
+				page_to_phys(vmalloc_to_page(temp_phys)),
+				domain);
+			goto out2;
+		}
+	}
+
+	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
+		goto out2;
+
+	return 0;
+
+out2:
+	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+out1:
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+						data->mapped_size);
+out:
+	return ret;
+}
+
 static struct ion_heap_ops vmalloc_ops = {
 	.allocate = ion_system_heap_allocate,
 	.free = ion_system_heap_free,
@@ -170,6 +275,8 @@
 	.map_user = ion_system_heap_map_user,
 	.cache_op = ion_system_heap_cache_ops,
 	.get_allocated = ion_system_heap_get_allocated,
+	.map_iommu = ion_system_heap_map_iommu,
+	.unmap_iommu = ion_system_heap_unmap_iommu,
 };
 
 struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
@@ -285,6 +392,74 @@
 	return atomic_read(&system_contig_heap_allocated);
 }
 
+int ion_system_contig_heap_map_iommu(struct ion_buffer *buffer,
+				struct ion_iommu_map *data,
+				unsigned int domain_num,
+				unsigned int partition_num,
+				unsigned long align,
+				unsigned long iova_length,
+				unsigned long flags)
+{
+	int ret, i;
+	struct iommu_domain *domain;
+	unsigned long temp_phys, temp_iova;
+	unsigned long extra;
+
+	if (!ION_IS_CACHED(flags))
+		return -EINVAL;
+
+	if (!msm_use_iommu()) {
+		data->iova_addr = virt_to_phys(buffer->vaddr);
+		return 0;
+	}
+
+	data->mapped_size = iova_length;
+	extra = iova_length - buffer->size;
+
+	data->iova_addr = msm_allocate_iova_address(domain_num, partition_num,
+						data->mapped_size, align);
+
+	if (!data->iova_addr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	domain = msm_get_iommu_domain(domain_num);
+
+	if (!domain) {
+		ret = -ENOMEM;
+		goto out1;
+	}
+	temp_iova = data->iova_addr;
+	temp_phys = virt_to_phys(buffer->vaddr);
+	for (i = buffer->size; i > 0; i -= SZ_4K, temp_iova += SZ_4K,
+						  temp_phys += SZ_4K) {
+		ret = iommu_map(domain, temp_iova,
+			temp_phys,
+			get_order(SZ_4K), ION_IS_CACHED(flags) ? 1 : 0);
+
+		if (ret) {
+			pr_err("%s: could not map %lx to %lx in domain %p\n",
+				__func__, temp_iova, temp_phys, domain);
+			goto out2;
+		}
+	}
+
+	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
+		goto out2;
+
+	return 0;
+out2:
+	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
+		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+
+out1:
+	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
+						data->mapped_size);
+out:
+	return ret;
+}
+
 static struct ion_heap_ops kmalloc_ops = {
 	.allocate = ion_system_contig_heap_allocate,
 	.free = ion_system_contig_heap_free,
@@ -296,6 +471,8 @@
 	.map_user = ion_system_contig_heap_map_user,
 	.cache_op = ion_system_contig_heap_cache_ops,
 	.get_allocated = ion_system_contig_heap_get_allocated,
+	.map_iommu = ion_system_contig_heap_map_iommu,
+	.unmap_iommu = ion_system_heap_unmap_iommu,
 };
 
 struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 54dd056..0c96eaf 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -89,6 +89,7 @@
 			heaps[i] = 0;
 			continue;
 		}
+
 		ion_device_add_heap(idev, heaps[i]);
 	}
 	platform_set_drvdata(pdev, idev);
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index b4cd286..39a7b04 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -1,7 +1,8 @@
-ccflags-y := -Iinclude/drm
+ccflags-y := -Iinclude/drm -Idrivers/gpu/msm
 
 msm_kgsl_core-y = \
 	kgsl.o \
+	kgsl_trace.o \
 	kgsl_sharedmem.o \
 	kgsl_pwrctrl.o \
 	kgsl_pwrscale.o \
@@ -20,11 +21,14 @@
 	adreno_drawctxt.o \
 	adreno_postmortem.o \
 	adreno_a2xx.o \
+	adreno_a2xx_trace.o \
 	adreno.o
 
 msm_adreno-$(CONFIG_DEBUG_FS) += adreno_debugfs.o
 
-msm_z180-y += z180.o
+msm_z180-y += \
+	z180.o \
+	z180_trace.o
 
 msm_kgsl_core-objs = $(msm_kgsl_core-y)
 msm_adreno-objs = $(msm_adreno-y)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 23ecfb3..2681263 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -149,6 +149,9 @@
 	{ ADRENO_REV_A225, 2, 2, 0, 5,
 		"a225p5_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
 		1536, 768 },
+	{ ADRENO_REV_A225, 2, 2, 0, 6,
+		"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
+		1536, 768 },
 	{ ADRENO_REV_A225, 2, 2, ANY_ID, ANY_ID,
 		"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
 		1536, 768 },
@@ -270,10 +273,13 @@
 	int sizedwords = 0;
 	unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */
 
-	/* If possible, then set the state via the command stream to avoid
-	   a CPU idle.  Otherwise, use the default setstate which uses register
-	   writes */
-	if (adreno_dev->drawctxt_active) {
+	/*
+	 * If possible, then set the state via the command stream to avoid
+	 * a CPU idle.  Otherwise, use the default setstate which uses register
+	 * writes For CFF dump we must idle and use the registers so that it is
+	 * easier to filter out the mmu accesses from the dump
+	 */
+	if (!kgsl_cff_dump_enable && adreno_dev->drawctxt_active) {
 		if (flags & KGSL_MMUFLAGS_PTUPDATE) {
 			/* wait for graphics pipe to be idle */
 			*cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
@@ -358,6 +364,7 @@
 {
 	unsigned int chipid = 0;
 	unsigned int coreid, majorid, minorid, patchid, revid;
+	uint32_t soc_platform_version = socinfo_get_version();
 
 	adreno_regread(device, REG_RBBM_PERIPHID1, &coreid);
 	adreno_regread(device, REG_RBBM_PERIPHID2, &majorid);
@@ -379,8 +386,12 @@
 	patchid = ((revid >> 16) & 0xFF);
 
 	/* 8x50 returns 0 for patch release, but it should be 1 */
+	/* 8960v3 returns 5 for patch release, but it should be 6 */
 	if (cpu_is_qsd8x50())
 		patchid = 1;
+	else if (cpu_is_msm8960() &&
+			SOCINFO_VERSION_MAJOR(soc_platform_version) == 3)
+		patchid = 6;
 
 	chipid |= (minorid << 8) | patchid;
 
@@ -926,29 +937,27 @@
 	return status;
 }
 
-uint8_t *kgsl_sharedmem_convertaddr(struct kgsl_device *device,
-	unsigned int pt_base, unsigned int gpuaddr, unsigned int *size)
+const struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
+						unsigned int pt_base,
+						unsigned int gpuaddr,
+						unsigned int size)
 {
-	uint8_t *result = NULL;
+	struct kgsl_memdesc *result = NULL;
 	struct kgsl_mem_entry *entry;
 	struct kgsl_process_private *priv;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct adreno_ringbuffer *ringbuffer = &adreno_dev->ringbuffer;
+	struct kgsl_context *context;
+	int next = 0;
 
-	if (kgsl_gpuaddr_in_memdesc(&ringbuffer->buffer_desc, gpuaddr)) {
-		return kgsl_gpuaddr_to_vaddr(&ringbuffer->buffer_desc,
-					gpuaddr, size);
-	}
+	if (kgsl_gpuaddr_in_memdesc(&ringbuffer->buffer_desc, gpuaddr, size))
+		return &ringbuffer->buffer_desc;
 
-	if (kgsl_gpuaddr_in_memdesc(&ringbuffer->memptrs_desc, gpuaddr)) {
-		return kgsl_gpuaddr_to_vaddr(&ringbuffer->memptrs_desc,
-					gpuaddr, size);
-	}
+	if (kgsl_gpuaddr_in_memdesc(&ringbuffer->memptrs_desc, gpuaddr, size))
+		return &ringbuffer->memptrs_desc;
 
-	if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr)) {
-		return kgsl_gpuaddr_to_vaddr(&device->memstore,
-					gpuaddr, size);
-	}
+	if (kgsl_gpuaddr_in_memdesc(&device->memstore, gpuaddr, size))
+		return &device->memstore;
 
 	mutex_lock(&kgsl_driver.process_mutex);
 	list_for_each_entry(priv, &kgsl_driver.process_list, list) {
@@ -958,8 +967,7 @@
 		entry = kgsl_sharedmem_find_region(priv, gpuaddr,
 						sizeof(unsigned int));
 		if (entry) {
-			result = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
-							gpuaddr, size);
+			result = &entry->memdesc;
 			spin_unlock(&priv->mem_lock);
 			mutex_unlock(&kgsl_driver.process_mutex);
 			return result;
@@ -970,14 +978,52 @@
 
 	BUG_ON(!mutex_is_locked(&device->mutex));
 	list_for_each_entry(entry, &device->memqueue, list) {
-		if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr)) {
-			result = kgsl_gpuaddr_to_vaddr(&entry->memdesc,
-							gpuaddr, size);
-			break;
+		if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size)) {
+			result = &entry->memdesc;
+			return result;
 		}
 
 	}
-	return result;
+
+	while (1) {
+		struct adreno_context *adreno_context = NULL;
+		struct kgsl_memdesc *gpustate;
+		struct kgsl_memdesc *gmemshadow;
+		context = idr_get_next(&device->context_idr, &next);
+		if (context == NULL)
+			break;
+
+		adreno_context = (struct adreno_context *)context->devctxt;
+
+		if (!kgsl_mmu_pt_equal(adreno_context->pagetable, pt_base))
+			continue;
+
+		gpustate = &adreno_context->gpustate;
+		if (kgsl_gpuaddr_in_memdesc(gpustate, gpuaddr, size)) {
+			result = gpustate;
+			return result;
+		}
+		gmemshadow = &adreno_context->context_gmem_shadow.gmemshadow;
+		if (kgsl_gpuaddr_in_memdesc(gmemshadow, gpuaddr, size)) {
+			result = gmemshadow;
+			return result;
+		}
+
+		next = next + 1;
+	}
+
+	return NULL;
+
+}
+
+uint8_t *adreno_convertaddr(struct kgsl_device *device, unsigned int pt_base,
+			    unsigned int gpuaddr, unsigned int size)
+{
+	const struct kgsl_memdesc *memdesc;
+
+	memdesc = adreno_find_region(device, pt_base, gpuaddr, size);
+
+	return memdesc ? kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr) : NULL;
 }
 
 void adreno_regread(struct kgsl_device *device, unsigned int offsetwords,
@@ -1271,6 +1317,18 @@
 	adreno_dev->gpudev->irq_control(adreno_dev, state);
 }
 
+static unsigned int adreno_gpuid(struct kgsl_device *device)
+{
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+	/* Standard KGSL gpuid format:
+	 * top word is 0x0002 for 2D or 0x0003 for 3D
+	 * Bottom word is core specific identifer
+	 */
+
+	return (0x0003 << 16) | ((int) adreno_dev->gpurev);
+}
+
 static const struct kgsl_functable adreno_functable = {
 	/* Mandatory functions */
 	.regread = adreno_regread,
@@ -1289,6 +1347,7 @@
 	.cleanup_pt = adreno_cleanup_pt,
 	.power_stats = adreno_power_stats,
 	.irqctrl = adreno_irqctrl,
+	.gpuid = adreno_gpuid,
 	/* Optional functions */
 	.setstate = adreno_setstate,
 	.drawctxt_create = adreno_drawctxt_create,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 0776a24..99c6c52 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -43,6 +43,7 @@
  */
 #define ADRENO_ISTORE_BYTES 12
 #define ADRENO_ISTORE_WORDS 3
+#define ADRENO_ISTORE_START 0x5000
 
 enum adreno_gpurev {
 	ADRENO_REV_UNKNOWN = 0,
@@ -93,8 +94,13 @@
 void adreno_regwrite(struct kgsl_device *device, unsigned int offsetwords,
 				unsigned int value);
 
-uint8_t *kgsl_sharedmem_convertaddr(struct kgsl_device *device,
-	unsigned int pt_base, unsigned int gpuaddr, unsigned int *size);
+const struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
+						unsigned int pt_base,
+						unsigned int gpuaddr,
+						unsigned int size);
+
+uint8_t *adreno_convertaddr(struct kgsl_device *device,
+	unsigned int pt_base, unsigned int gpuaddr, unsigned int size);
 
 static inline int adreno_is_a200(struct adreno_device *adreno_dev)
 {
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 7b27f61..d083586 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -15,6 +15,7 @@
 #include "kgsl_sharedmem.h"
 #include "kgsl_cffdump.h"
 #include "adreno.h"
+#include "adreno_a2xx_trace.h"
 
 /*
  *
@@ -598,7 +599,7 @@
 
 	/* Repartition shaders */
 	*cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
-	*cmds++ = 0x180;
+	*cmds++ = adreno_dev->pix_shader_start;
 
 	/* Invalidate Vertex & Pixel instruction code address and sizes */
 	*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
@@ -800,7 +801,7 @@
 
 	/* Repartition shaders */
 	*cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
-	*cmds++ = 0x180;
+	*cmds++ = adreno_dev->pix_shader_start;
 
 	/* Invalidate Vertex & Pixel instruction code address and sizes */
 	*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
@@ -1511,6 +1512,9 @@
 		KGSL_DRV_WARN(device,
 			"Looped %d times to read REG_CP_INT_STATUS\n",
 			num_reads);
+
+	trace_kgsl_a2xx_irq_status(device, master_status, status);
+
 	if (!status) {
 		if (master_status & MASTER_INT_SIGNAL__CP_INT_STAT) {
 			/* This indicates that we could not read CP_INT_STAT.
diff --git a/drivers/gpu/msm/adreno_a2xx_trace.c b/drivers/gpu/msm/adreno_a2xx_trace.c
new file mode 100644
index 0000000..c91d1a0
--- /dev/null
+++ b/drivers/gpu/msm/adreno_a2xx_trace.c
@@ -0,0 +1,19 @@
+/* Copyright (c) 2011, 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 "kgsl.h"
+#include "adreno.h"
+
+/* Instantiate tracepoints */
+#define CREATE_TRACE_POINTS
+#include "adreno_a2xx_trace.h"
diff --git a/drivers/gpu/msm/adreno_a2xx_trace.h b/drivers/gpu/msm/adreno_a2xx_trace.h
new file mode 100644
index 0000000..2528e15
--- /dev/null
+++ b/drivers/gpu/msm/adreno_a2xx_trace.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2011, 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.
+ *
+ */
+
+#if !defined(_ADRENO_A2XX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _ADRENO_A2XX_TRACE_H
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kgsl
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE adreno_a2xx_trace
+
+#include <linux/tracepoint.h>
+
+struct kgsl_device;
+
+/*
+ * Tracepoint for a2xx irq. Includes status info
+ */
+TRACE_EVENT(kgsl_a2xx_irq_status,
+
+	TP_PROTO(struct kgsl_device *device, unsigned int master_status,
+		 unsigned int status),
+
+	TP_ARGS(device, master_status, status),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(unsigned int, master_status)
+		__field(unsigned int, status)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->master_status = master_status;
+		__entry->status = status;
+	),
+
+	TP_printk(
+		"d_name=%s master=%s status=%s",
+		__get_str(device_name),
+		__entry->master_status ? __print_flags(__entry->master_status,
+			"|",
+			{ MASTER_INT_SIGNAL__MH_INT_STAT, "MH" },
+			{ MASTER_INT_SIGNAL__SQ_INT_STAT, "SQ" },
+			{ MASTER_INT_SIGNAL__CP_INT_STAT, "CP" },
+			{ MASTER_INT_SIGNAL__RBBM_INT_STAT, "RBBM" }) : "None",
+		__entry->status ? __print_flags(__entry->status, "|",
+			{ CP_INT_CNTL__SW_INT_MASK, "SW" },
+			{ CP_INT_CNTL__T0_PACKET_IN_IB_MASK,
+				"T0_PACKET_IN_IB" },
+			{ CP_INT_CNTL__OPCODE_ERROR_MASK, "OPCODE_ERROR" },
+			{ CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK,
+				"PROTECTED_MODE_ERROR" },
+			{ CP_INT_CNTL__RESERVED_BIT_ERROR_MASK,
+				"RESERVED_BIT_ERROR" },
+			{ CP_INT_CNTL__IB_ERROR_MASK, "IB_ERROR" },
+			{ CP_INT_CNTL__IB2_INT_MASK, "IB2" },
+			{ CP_INT_CNTL__IB1_INT_MASK, "IB1" },
+			{ CP_INT_CNTL__RB_INT_MASK, "RB" }) : "None"
+	)
+);
+
+#endif /* _ADRENO_A2XX_TRACE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index 419ce9d..c1b9e4c 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -25,9 +25,6 @@
 unsigned int kgsl_cff_dump_enable;
 int kgsl_pm_regs_enabled;
 
-static uint32_t kgsl_ib_base;
-static uint32_t kgsl_ib_size;
-
 static struct dentry *pm_d_debugfs;
 
 static int pm_dump_set(void *data, u64 val)
@@ -115,98 +112,6 @@
 	return ss;
 }
 
-static ssize_t kgsl_ib_dump_read(
-	struct file *file,
-	char __user *buff,
-	size_t buff_count,
-	loff_t *ppos)
-{
-	int i, count = kgsl_ib_size, remaining, pos = 0, tot = 0, ss;
-	struct kgsl_device *device = file->private_data;
-	const int rowc = 32;
-	unsigned int pt_base, ib_memsize;
-	uint8_t *base_addr;
-	char linebuf[80];
-
-	if (!ppos || !device || !kgsl_ib_base)
-		return 0;
-
-	kgsl_regread(device, MH_MMU_PT_BASE, &pt_base);
-	base_addr = kgsl_sharedmem_convertaddr(device, pt_base, kgsl_ib_base,
-		&ib_memsize);
-
-	if (!base_addr)
-		return 0;
-
-	pr_info("%s ppos=%ld, buff_count=%d, count=%d\n", __func__, (long)*ppos,
-		buff_count, count);
-	ss = snprintf(linebuf, sizeof(linebuf), "IB: base=%08x(%08x"
-		"), size=%d, memsize=%d\n", kgsl_ib_base,
-		(uint32_t)base_addr, kgsl_ib_size, ib_memsize);
-	if (*ppos == 0) {
-		if (copy_to_user(buff, linebuf, ss+1))
-			return -EFAULT;
-		tot += ss;
-		buff += ss;
-		*ppos += ss;
-	}
-	pos += ss;
-	remaining = count;
-	for (i = 0; i < count; i += rowc) {
-		int linec = min(remaining, rowc);
-
-		remaining -= rowc;
-		ss = kgsl_hex_dump("IB: %05x: ", i, base_addr, rowc, linec,
-			buff);
-		if (ss < 0)
-			return ss;
-
-		if (pos >= *ppos) {
-			if (tot+ss >= buff_count) {
-				ss = copy_to_user(buff, "", 1);
-				return tot;
-			}
-			tot += ss;
-			buff += ss;
-			*ppos += ss;
-		}
-		pos += ss;
-		base_addr += linec;
-	}
-
-	return tot;
-}
-
-static ssize_t kgsl_ib_dump_write(
-	struct file *file,
-	const char __user *buff,
-	size_t count,
-	loff_t *ppos)
-{
-	char local_buff[64];
-
-	if (count >= sizeof(local_buff))
-		return -EFAULT;
-
-	if (copy_from_user(local_buff, buff, count))
-		return -EFAULT;
-
-	local_buff[count] = 0;	/* end of string */
-	sscanf(local_buff, "%x %d", &kgsl_ib_base, &kgsl_ib_size);
-
-	pr_info("%s: base=%08X size=%d\n", __func__, kgsl_ib_base,
-		kgsl_ib_size);
-
-	return count;
-}
-
-static const struct file_operations kgsl_ib_dump_fops = {
-	.open = kgsl_dbgfs_open,
-	.release = kgsl_dbgfs_release,
-	.read = kgsl_ib_dump_read,
-	.write = kgsl_ib_dump_write,
-};
-
 static int kgsl_regread_nolock(struct kgsl_device *device,
 	unsigned int offsetwords, unsigned int *value)
 {
@@ -223,7 +128,6 @@
 	return 0;
 }
 
-#define ADRENO_ISTORE_START 0x5000
 static ssize_t kgsl_istore_read(
 	struct file *file,
 	char __user *buff,
@@ -429,8 +333,6 @@
 	if (!device->d_debugfs || IS_ERR(device->d_debugfs))
 		return;
 
-	debugfs_create_file("ib_dump",  0600, device->d_debugfs, device,
-			    &kgsl_ib_dump_fops);
 	debugfs_create_file("istore",   0400, device->d_debugfs, device,
 			    &kgsl_istore_fops);
 	debugfs_create_file("sx_debug", 0400, device->d_debugfs, device,
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index cc69360..c6b850e 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -247,9 +247,8 @@
 static void dump_ib(struct kgsl_device *device, char* buffId, uint32_t pt_base,
 	uint32_t base_offset, uint32_t ib_base, uint32_t ib_size, bool dump)
 {
-	unsigned int memsize;
-	uint8_t *base_addr = kgsl_sharedmem_convertaddr(device, pt_base,
-		ib_base, &memsize);
+	uint8_t *base_addr = adreno_convertaddr(device, pt_base,
+		ib_base, ib_size*sizeof(uint32_t));
 
 	if (base_addr && dump)
 		print_hex_dump(KERN_ERR, buffId, DUMP_PREFIX_OFFSET,
@@ -277,14 +276,13 @@
 	int i, j;
 	uint32_t value;
 	uint32_t *ib1_addr;
-	unsigned int memsize;
 
 	dump_ib(device, "IB1:", pt_base, base_offset, ib1_base,
 		ib1_size, dump);
 
 	/* fetch virtual address for given IB base */
-	ib1_addr = (uint32_t *)kgsl_sharedmem_convertaddr(device, pt_base,
-		ib1_base, &memsize);
+	ib1_addr = (uint32_t *)adreno_convertaddr(device, pt_base,
+		ib1_base, ib1_size*sizeof(uint32_t));
 	if (!ib1_addr)
 		return;
 
@@ -466,7 +464,7 @@
 	const uint32_t *rb_vaddr;
 	int num_item = 0;
 	int read_idx, write_idx;
-	unsigned int ts_processed, rb_memsize;
+	unsigned int ts_processed;
 
 	static struct ib_list ib_list;
 
@@ -681,11 +679,16 @@
 
 	KGSL_LOG_DUMP(device, "RB: rd_addr:%8.8x  rb_size:%d  num_item:%d\n",
 		cp_rb_base, rb_count<<2, num_item);
-	rb_vaddr = (const uint32_t *)kgsl_sharedmem_convertaddr(device,
-			cur_pt_base, cp_rb_base, &rb_memsize);
+
+	if (adreno_dev->ringbuffer.buffer_desc.gpuaddr != cp_rb_base)
+		KGSL_LOG_POSTMORTEM_WRITE(device,
+			"rb address mismatch, should be 0x%08x\n",
+			adreno_dev->ringbuffer.buffer_desc.gpuaddr);
+
+	rb_vaddr = adreno_dev->ringbuffer.buffer_desc.hostptr;
 	if (!rb_vaddr) {
 		KGSL_LOG_POSTMORTEM_WRITE(device,
-			"Can't fetch vaddr for CP_RB_BASE\n");
+			"rb has no kernel mapping!\n");
 		goto error_vfree;
 	}
 
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 53b9e8a..7a42dcd 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -33,6 +33,7 @@
 #include "kgsl_log.h"
 #include "kgsl_sharedmem.h"
 #include "kgsl_device.h"
+#include "kgsl_trace.h"
 
 #undef MODULE_PARAM_PREFIX
 #define MODULE_PARAM_PREFIX "kgsl."
@@ -773,9 +774,7 @@
 	BUG_ON(private == NULL);
 
 	list_for_each_entry(entry, &private->mem_list, list) {
-		if (gpuaddr >= entry->memdesc.gpuaddr &&
-		    ((gpuaddr + size) <=
-			(entry->memdesc.gpuaddr + entry->memdesc.size))) {
+		if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size)) {
 			result = entry;
 			break;
 		}
@@ -785,20 +784,6 @@
 }
 EXPORT_SYMBOL(kgsl_sharedmem_find_region);
 
-uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
-	unsigned int gpuaddr, unsigned int *size)
-{
-	BUG_ON(memdesc->hostptr == NULL);
-
-	if (memdesc->gpuaddr == 0 || (gpuaddr < memdesc->gpuaddr ||
-		gpuaddr >= memdesc->gpuaddr + memdesc->size))
-		return NULL;
-
-	*size = memdesc->size - (gpuaddr - memdesc->gpuaddr);
-	return memdesc->hostptr + (gpuaddr - memdesc->gpuaddr);
-}
-EXPORT_SYMBOL(kgsl_gpuaddr_to_vaddr);
-
 /*call all ioctl sub functions with driver locked*/
 static long kgsl_ioctl_device_getproperty(struct kgsl_device_private *dev_priv,
 					  unsigned int cmd, void *data)
@@ -847,10 +832,14 @@
 
 	dev_priv->device->active_cnt++;
 
+	trace_kgsl_waittimestamp_entry(dev_priv->device, param);
+
 	result = dev_priv->device->ftbl->waittimestamp(dev_priv->device,
 					param->timestamp,
 					param->timeout);
 
+	trace_kgsl_waittimestamp_exit(dev_priv->device, result);
+
 	/* Fire off any pending suspend operations that are in flight */
 
 	INIT_COMPLETION(dev_priv->device->suspend_gate);
@@ -975,6 +964,8 @@
 					     &param->timestamp,
 					     param->flags);
 
+	trace_kgsl_issueibcmds(dev_priv->device, param, result);
+
 	if (result != 0)
 		goto free_ibdesc;
 
@@ -1008,6 +999,8 @@
 		dev_priv->device->ftbl->readtimestamp(dev_priv->device,
 		param->type);
 
+	trace_kgsl_readtimestamp(dev_priv->device, param);
+
 	return 0;
 }
 
@@ -1671,11 +1664,6 @@
 		result = -EINVAL;
 		goto done;
 	}
-	if (!entry->memdesc.hostptr)
-		entry->memdesc.hostptr =
-				kgsl_gpuaddr_to_vaddr(&entry->memdesc,
-					param->gpuaddr, &entry->memdesc.size);
-
 	if (!entry->memdesc.hostptr) {
 		KGSL_CORE_ERR("invalid hostptr with gpuaddr %08x\n",
 			param->gpuaddr);
@@ -1897,7 +1885,7 @@
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_CFF_USER_EVENT,
 			kgsl_ioctl_cff_user_event, 0),
 	KGSL_IOCTL_FUNC(IOCTL_KGSL_TIMESTAMP_EVENT,
-			kgsl_ioctl_timestamp_event, 0),
+			kgsl_ioctl_timestamp_event, 1),
 };
 
 static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
@@ -2447,8 +2435,6 @@
 	if (result)
 		goto err;
 
-	kgsl_mmu_set_mmutype(ksgl_mmu_type);
-
 	return 0;
 
 err:
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 3bb722d..1135adb 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -145,8 +145,6 @@
 #endif
 
 void kgsl_mem_entry_destroy(struct kref *kref);
-uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
-	unsigned int gpuaddr, unsigned int *size);
 struct kgsl_mem_entry *kgsl_sharedmem_find_region(
 	struct kgsl_process_private *private, unsigned int gpuaddr,
 	size_t size);
@@ -175,14 +173,24 @@
 #endif
 
 static inline int kgsl_gpuaddr_in_memdesc(const struct kgsl_memdesc *memdesc,
-				unsigned int gpuaddr)
+				unsigned int gpuaddr, unsigned int size)
 {
-	if (gpuaddr >= memdesc->gpuaddr && (gpuaddr + sizeof(unsigned int)) <=
-		(memdesc->gpuaddr + memdesc->size)) {
+	if (gpuaddr >= memdesc->gpuaddr &&
+	    ((gpuaddr + size) <= (memdesc->gpuaddr + memdesc->size))) {
 		return 1;
 	}
 	return 0;
 }
+static inline uint8_t *kgsl_gpuaddr_to_vaddr(const struct kgsl_memdesc *memdesc,
+					     unsigned int gpuaddr)
+{
+	if (memdesc->hostptr == NULL || memdesc->gpuaddr == 0 ||
+		(gpuaddr < memdesc->gpuaddr ||
+		gpuaddr >= memdesc->gpuaddr + memdesc->size))
+		return NULL;
+
+	return memdesc->hostptr + (gpuaddr - memdesc->gpuaddr);
+}
 
 static inline int timestamp_cmp(unsigned int new, unsigned int old)
 {
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index aa33152..e9455cb 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -231,8 +231,6 @@
 
 	spin_lock(&cffdump_lock);
 	if (opcode == CFF_OP_WRITE_MEM) {
-		if (op1 < 0x40000000 || op1 >= 0x60000000)
-			KGSL_CORE_ERR("addr out-of-range: op1=%08x", op1);
 		if ((cff_op_write_membuf.addr != op1 &&
 			cff_op_write_membuf.count)
 			|| (cff_op_write_membuf.count == MEMBUF_SIZE))
@@ -360,15 +358,7 @@
 
 void kgsl_cffdump_open(enum kgsl_deviceid device_id)
 {
-	/*TODO: move this to where we can report correct gmemsize*/
-	unsigned int va_base;
-
-	if (cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_msm8930())
-		va_base = 0x40000000;
-	else
-		va_base = 0x20000000;
-
-	kgsl_cffdump_memory_base(device_id, va_base,
+	kgsl_cffdump_memory_base(device_id, KGSL_PAGETABLE_BASE,
 			CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, SZ_256K);
 }
 
@@ -401,8 +391,6 @@
 	bool clean_cache)
 {
 	const void *src;
-	uint host_size;
-	uint physaddr;
 
 	if (!kgsl_cff_dump_enable)
 		return;
@@ -422,13 +410,9 @@
 		}
 		memdesc = &entry->memdesc;
 	}
-	BUG_ON(memdesc->gpuaddr == 0);
-	BUG_ON(gpuaddr == 0);
-	physaddr = kgsl_get_realaddr(memdesc) + (gpuaddr - memdesc->gpuaddr);
-
-	src = kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr, &host_size);
-	if (src == NULL || host_size < sizebytes) {
-		KGSL_CORE_ERR("did not find mapping for "
+	src = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr);
+	if (memdesc->hostptr == NULL) {
+		KGSL_CORE_ERR("no kernel mapping for "
 			"gpuaddr: 0x%08x, m->host: 0x%p, phys: 0x%08x\n",
 			gpuaddr, memdesc->hostptr, memdesc->physaddr);
 		return;
@@ -444,7 +428,6 @@
 				KGSL_CACHE_OP_INV);
 	}
 
-	BUG_ON(physaddr > 0x66000000 && physaddr < 0x66ffffff);
 	while (sizebytes > 3) {
 		cffdump_printline(-1, CFF_OP_WRITE_MEM, gpuaddr, *(uint *)src,
 			0, 0, 0);
@@ -462,7 +445,6 @@
 	if (!kgsl_cff_dump_enable)
 		return;
 
-	BUG_ON(addr > 0x66000000 && addr < 0x66ffffff);
 	while (sizebytes > 3) {
 		/* Use 32bit memory writes as long as there's at least
 		 * 4 bytes left */
@@ -575,7 +557,6 @@
 {
 	static uint level; /* recursion level */
 	bool ret = true;
-	uint host_size;
 	uint *hostaddr, *hoststart;
 	int dwords_left = sizedwords; /* dwords left in the current command
 					 buffer */
@@ -596,10 +577,9 @@
 		}
 		memdesc = &entry->memdesc;
 	}
-
-	hostaddr = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr, &host_size);
+	hostaddr = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr);
 	if (hostaddr == NULL) {
-		KGSL_CORE_ERR("did not find mapping for "
+		KGSL_CORE_ERR("no kernel mapping for "
 			"gpuaddr: 0x%08x\n", gpuaddr);
 		return true;
 	}
@@ -608,14 +588,9 @@
 
 	level++;
 
-	if (!memdesc->physaddr) {
-		KGSL_CORE_ERR("no physaddr");
-	} else {
-		mb();
-		kgsl_cache_range_op((struct kgsl_memdesc *)memdesc,
+	mb();
+	kgsl_cache_range_op((struct kgsl_memdesc *)memdesc,
 				KGSL_CACHE_OP_INV);
-	}
-
 #ifdef DEBUG
 	pr_info("kgsl: cffdump: ib: gpuaddr:0x%08x, wc:%d, hptr:%p\n",
 		gpuaddr, sizedwords, hostaddr);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index c88f16ef..3ef11ce 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -89,6 +89,7 @@
 	void (*power_stats)(struct kgsl_device *device,
 		struct kgsl_power_stats *stats);
 	void (*irqctrl)(struct kgsl_device *device, int state);
+	unsigned int (*gpuid)(struct kgsl_device *device);
 	/* Optional functions - these functions are not mandatory.  The
 	   driver will check that the function pointer is not NULL before
 	   calling the hook */
@@ -240,6 +241,11 @@
 	return device->ftbl->idle(device, timeout);
 }
 
+static inline unsigned int kgsl_gpuid(struct kgsl_device *device)
+{
+	return device->ftbl->gpuid(device);
+}
+
 static inline int kgsl_create_device_sysfs_files(struct device *root,
 	const struct device_attribute **list)
 {
@@ -277,10 +283,11 @@
 
 static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
 {
-	device->work_queue = create_workqueue(device->name);
+	device->work_queue = create_singlethread_workqueue(device->name);
 	if (!device->work_queue) {
-		KGSL_DRV_ERR(device, "create_workqueue(%s) failed\n",
-			device->name);
+		KGSL_DRV_ERR(device,
+			     "create_singlethread_workqueue(%s) failed\n",
+			     device->name);
 		return -EINVAL;
 	}
 	return 0;
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 715b9d6..36248ef 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -22,6 +22,7 @@
 #include "kgsl_mmu.h"
 #include "kgsl_device.h"
 #include "kgsl_sharedmem.h"
+#include "adreno_postmortem.h"
 
 #define KGSL_MMU_ALIGN_SHIFT    13
 #define KGSL_MMU_ALIGN_MASK     (~((1 << KGSL_MMU_ALIGN_SHIFT) - 1))
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index b59761d..ec91b39 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -655,7 +655,7 @@
 	BUG_ON(memdesc == NULL || memdesc->hostptr == NULL);
 	BUG_ON(offsetbytes + sizeof(unsigned int) > memdesc->size);
 
-	kgsl_cffdump_setmem(memdesc->physaddr + offsetbytes,
+	kgsl_cffdump_setmem(memdesc->gpuaddr + offsetbytes,
 		src, sizeof(uint));
 	writel_relaxed(src, memdesc->hostptr + offsetbytes);
 	return 0;
@@ -669,8 +669,8 @@
 	BUG_ON(memdesc == NULL || memdesc->hostptr == NULL);
 	BUG_ON(offsetbytes + sizebytes > memdesc->size);
 
-	kgsl_cffdump_setmem(memdesc->physaddr + offsetbytes, value,
-		sizebytes);
+	kgsl_cffdump_setmem(memdesc->gpuaddr + offsetbytes, value,
+			    sizebytes);
 	memset(memdesc->hostptr + offsetbytes, value, sizebytes);
 	return 0;
 }
diff --git a/drivers/gpu/msm/kgsl_trace.c b/drivers/gpu/msm/kgsl_trace.c
new file mode 100644
index 0000000..2bcca15
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_trace.c
@@ -0,0 +1,19 @@
+/* Copyright (c) 2011, 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 "kgsl.h"
+#include "kgsl_device.h"
+
+/* Instantiate tracepoints */
+#define CREATE_TRACE_POINTS
+#include "kgsl_trace.h"
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
new file mode 100644
index 0000000..7c14ac1
--- /dev/null
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -0,0 +1,161 @@
+/* Copyright (c) 2011, 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.
+ *
+ */
+
+#if !defined(_KGSL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _KGSL_TRACE_H
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kgsl
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE kgsl_trace
+
+#include <linux/tracepoint.h>
+
+struct kgsl_device;
+struct kgsl_ringbuffer_issueibcmds;
+struct kgsl_device_waittimestamp;
+
+/*
+ * Tracepoint for kgsl issue ib commands
+ */
+TRACE_EVENT(kgsl_issueibcmds,
+
+	TP_PROTO(struct kgsl_device *device,
+			struct kgsl_ringbuffer_issueibcmds *cmd, int result),
+
+	TP_ARGS(device, cmd, result),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(unsigned int, drawctxt_id)
+		__field(unsigned int, ibdesc_addr)
+		__field(unsigned int, numibs)
+		__field(unsigned int, timestamp)
+		__field(unsigned int, flags)
+		__field(int, result)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->drawctxt_id = cmd->drawctxt_id;
+		__entry->ibdesc_addr = cmd->ibdesc_addr;
+		__entry->numibs = cmd->numibs;
+		__entry->timestamp = cmd->timestamp;
+		__entry->flags = cmd->flags;
+		__entry->result = result;
+	),
+
+	TP_printk(
+		"d_name=%s ctx=%u ib=%u numibs=%u timestamp=%u "
+		"flags=%u result=%d",
+		__get_str(device_name),
+		__entry->drawctxt_id,
+		__entry->ibdesc_addr,
+		__entry->numibs,
+		__entry->timestamp,
+		__entry->flags,
+		__entry->result
+	)
+);
+
+/*
+ * Tracepoint for kgsl readtimestamp
+ */
+TRACE_EVENT(kgsl_readtimestamp,
+
+	TP_PROTO(struct kgsl_device *device,
+			struct kgsl_cmdstream_readtimestamp *cmd),
+
+	TP_ARGS(device, cmd),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(unsigned int, type)
+		__field(unsigned int, timestamp)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->type = cmd->type;
+		__entry->timestamp = cmd->timestamp;
+	),
+
+	TP_printk(
+		"d_name=%s type=%u timestamp=%u",
+		__get_str(device_name),
+		__entry->type,
+		__entry->timestamp
+	)
+);
+
+/*
+ * Tracepoint for kgsl waittimestamp entry
+ */
+TRACE_EVENT(kgsl_waittimestamp_entry,
+
+	TP_PROTO(struct kgsl_device *device,
+			struct kgsl_device_waittimestamp *cmd),
+
+	TP_ARGS(device, cmd),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(unsigned int, timestamp)
+		__field(unsigned int, timeout)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->timestamp = cmd->timestamp;
+		__entry->timeout = cmd->timeout;
+	),
+
+	TP_printk(
+		"d_name=%s timestamp=%u timeout=%u",
+		__get_str(device_name),
+		__entry->timestamp,
+		__entry->timeout
+	)
+);
+
+/*
+ * Tracepoint for kgsl waittimestamp exit
+ */
+TRACE_EVENT(kgsl_waittimestamp_exit,
+
+	TP_PROTO(struct kgsl_device *device, int result),
+
+	TP_ARGS(device, result),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(int, result)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->result = result;
+	),
+
+	TP_printk(
+		"d_name=%s result=%d",
+		__get_str(device_name),
+		__entry->result
+	)
+);
+#endif /* _KGSL_TRACE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index cdb9c23..cf74e64 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -18,6 +18,7 @@
 
 #include "z180.h"
 #include "z180_reg.h"
+#include "z180_trace.h"
 
 #define DRIVER_VERSION_MAJOR   3
 #define DRIVER_VERSION_MINOR   1
@@ -213,6 +214,8 @@
 
 	z180_regread(device, ADDR_VGC_IRQSTATUS >> 2, &status);
 
+	trace_kgsl_z180_irq_status(device, status);
+
 	if (status & GSL_VGC_INT_MASK) {
 		z180_regwrite(device,
 			ADDR_VGC_IRQSTATUS >> 2, status & GSL_VGC_INT_MASK);
@@ -885,6 +888,16 @@
 	}
 }
 
+static unsigned int z180_gpuid(struct kgsl_device *device)
+{
+	/* Standard KGSL gpuid format:
+	 * top word is 0x0002 for 2D or 0x0003 for 3D
+	 * Bottom word is core specific identifer
+	 */
+
+	return (0x0002 << 16) | 180;
+}
+
 static const struct kgsl_functable z180_functable = {
 	/* Mandatory functions */
 	.regread = z180_regread,
@@ -902,6 +915,7 @@
 	.cleanup_pt = z180_cleanup_pt,
 	.power_stats = z180_power_stats,
 	.irqctrl = z180_irqctrl,
+	.gpuid = z180_gpuid,
 	/* Optional functions */
 	.drawctxt_create = NULL,
 	.drawctxt_destroy = z180_drawctxt_destroy,
diff --git a/drivers/gpu/msm/z180_trace.c b/drivers/gpu/msm/z180_trace.c
new file mode 100644
index 0000000..29b519c
--- /dev/null
+++ b/drivers/gpu/msm/z180_trace.c
@@ -0,0 +1,20 @@
+/* Copyright (c) 2011, 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 "kgsl.h"
+#include "z180.h"
+#include "z180_reg.h"
+
+/* Instantiate tracepoints */
+#define CREATE_TRACE_POINTS
+#include "z180_trace.h"
diff --git a/drivers/gpu/msm/z180_trace.h b/drivers/gpu/msm/z180_trace.h
new file mode 100644
index 0000000..fbe1fe5
--- /dev/null
+++ b/drivers/gpu/msm/z180_trace.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2011, 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.
+ *
+ */
+
+#if !defined(_Z180_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _Z180_TRACE_H
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kgsl
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE z180_trace
+
+#include <linux/tracepoint.h>
+
+struct kgsl_device;
+
+/*
+ * Tracepoint for z180 irq. Includes status info
+ */
+TRACE_EVENT(kgsl_z180_irq_status,
+
+	TP_PROTO(struct kgsl_device *device, unsigned int status),
+
+	TP_ARGS(device, status),
+
+	TP_STRUCT__entry(
+		__string(device_name, device->name)
+		__field(unsigned int, status)
+	),
+
+	TP_fast_assign(
+		__assign_str(device_name, device->name);
+		__entry->status = status;
+	),
+
+	TP_printk(
+		"d_name=%s status=%s",
+		__get_str(device_name),
+		__entry->status ? __print_flags(__entry->status, "|",
+			{ REG_VGC_IRQSTATUS__MH_MASK, "MH" },
+			{ REG_VGC_IRQSTATUS__G2D_MASK, "G2D" },
+			{ REG_VGC_IRQSTATUS__FIFO_MASK, "FIFO" }) : "None"
+	)
+);
+
+#endif /* _Z180_TRACE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 5c5f9db..6e7dd68 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -400,7 +400,7 @@
 	struct evdev_client *client = file->private_data;
 	struct evdev *evdev = client->evdev;
 	struct input_event event;
-	int retval;
+	int retval = 0;
 
 	if (count < input_event_size())
 		return -EINVAL;
diff --git a/drivers/input/misc/pmic8058-othc.c b/drivers/input/misc/pmic8058-othc.c
index a28e8e1..cac748a 100644
--- a/drivers/input/misc/pmic8058-othc.c
+++ b/drivers/input/misc/pmic8058-othc.c
@@ -536,19 +536,11 @@
 	struct pm8058_othc *dd =
 		container_of(work, struct pm8058_othc, detect_work.work);
 
-	if (dd->othc_ir_state) {
-		/* inserted */
-		rc = pm8058_accessory_report(dd, 1);
-		if (rc)
-			pr_err("Accessory could not be detected\n");
-	} else {
-		/* removed */
-		rc = pm8058_accessory_report(dd, 0);
-		if (rc)
-			pr_err("Accessory could not be detected\n");
-		/* Clear existing switch state */
-		dd->othc_sw_state = false;
-	}
+	/* Accessory has been inserted */
+	rc = pm8058_accessory_report(dd, 1);
+	if (rc)
+		pr_err("Accessory insertion could not be detected\n");
+
 	enable_irq(dd->othc_irq_ir);
 }
 
@@ -637,8 +629,6 @@
 		ktime_set((dd->switch_debounce_ms / 1000),
 		(dd->switch_debounce_ms % 1000) * 1000000), HRTIMER_MODE_REL);
 
-	/* disable irq, this gets enabled in the workqueue */
-	disable_irq_nosync(dd->othc_irq_ir);
 
 	/* Check the MIC_BIAS status, to check if inserted or removed */
 	rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
@@ -648,8 +638,20 @@
 	}
 
 	dd->othc_ir_state = rc;
-	schedule_delayed_work(&dd->detect_work,
+	if (dd->othc_ir_state) {
+		/* disable irq, this gets enabled in the workqueue */
+		disable_irq_nosync(dd->othc_irq_ir);
+		/* Accessory has been inserted, report with detection delay */
+		schedule_delayed_work(&dd->detect_work,
 				msecs_to_jiffies(dd->detection_delay_ms));
+	} else {
+		/* Accessory has been removed, report removal immediately */
+		rc = pm8058_accessory_report(dd, 0);
+		if (rc)
+			pr_err("Accessory removal could not be detected\n");
+		/* Clear existing switch state */
+		dd->othc_sw_state = false;
+	}
 
 fail_ir:
 	return IRQ_HANDLED;
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c
index 2225b7a..f0da3e8 100644
--- a/drivers/input/misc/pmic8xxx-pwrkey.c
+++ b/drivers/input/misc/pmic8xxx-pwrkey.c
@@ -100,7 +100,9 @@
 		return -EINVAL;
 	}
 
-	if (pdata->kpd_trigger_delay_us > 62500) {
+	/* Valid range of pwr key trigger delay is 1/64 sec to 2 seconds. */
+	if (pdata->kpd_trigger_delay_us > USEC_PER_SEC * 2 ||
+		pdata->kpd_trigger_delay_us < USEC_PER_SEC / 64) {
 		dev_err(&pdev->dev, "invalid power key trigger delay\n");
 		return -EINVAL;
 	}
@@ -124,8 +126,8 @@
 	pwr->phys = "pmic8xxx_pwrkey/input0";
 	pwr->dev.parent = &pdev->dev;
 
-	delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC;
-	delay = 1 + ilog2(delay);
+	delay = (pdata->kpd_trigger_delay_us << 6) / USEC_PER_SEC;
+	delay = ilog2(delay);
 
 	err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl);
 	if (err < 0) {
diff --git a/drivers/input/touchscreen/synaptics/rmi_f11.c b/drivers/input/touchscreen/synaptics/rmi_f11.c
index 9a23776..4caaf92 100644
--- a/drivers/input/touchscreen/synaptics/rmi_f11.c
+++ b/drivers/input/touchscreen/synaptics/rmi_f11.c
@@ -188,11 +188,7 @@
 		}
 	}
 	input_report_key(function_device->input,
-			BTN_TOUCH, fingerDownCount);
-	for (finger = 0; finger < (instanceData->sensorInfo->numberOfFingers - 1); finger++) {
-		input_report_key(function_device->input,
-			BTN_2 + finger, fingerDownCount >= (finger + 2));
-	}
+			BTN_TOUCH, !!fingerDownCount);
 
 	for (finger = 0; finger < instanceData->sensorInfo->numberOfFingers; finger++) {
 		int reg;
@@ -269,14 +265,8 @@
 				}
 #ifdef CONFIG_SYNA_MULTI_TOUCH
 				/* Report Multi-Touch events for each finger */
-				/* major axis of touch area ellipse */
-				input_report_abs(function_device->input, ABS_MT_TOUCH_MAJOR, Z);
-				/* minor axis of touch area ellipse */
-				input_report_abs(function_device->input, ABS_MT_WIDTH_MAJOR,
-						max(Wx, Wy));
-				/* Currently only 2 supported - 1 or 0 */
-				input_report_abs(function_device->input, ABS_MT_ORIENTATION,
-					(Wx > Wy ? 1 : 0));
+				input_report_abs(function_device->input,
+							ABS_MT_PRESSURE, Z);
 				input_report_abs(function_device->input, ABS_MT_POSITION_X, X);
 				input_report_abs(function_device->input, ABS_MT_POSITION_Y, Y);
 
@@ -284,7 +274,7 @@
 				/* Could be formed by keeping an id per position and assiging */
 				/* a new id when fingerStatus changes for that position.*/
 				input_report_abs(function_device->input, ABS_MT_TRACKING_ID,
-						finger+1);
+						finger);
 				/* MT sync between fingers */
 				input_mt_sync(function_device->input);
 #endif
@@ -297,17 +287,10 @@
 		instanceData->wasdown = false;
 
 #ifdef CONFIG_SYNA_MULTI_TOUCH
-		input_report_abs(function_device->input, ABS_MT_TOUCH_MAJOR, 0);
-		input_report_abs(function_device->input, ABS_MT_WIDTH_MAJOR, 0);
-		input_report_abs(function_device->input, ABS_MT_POSITION_X, instanceData->oldX);
-		input_report_abs(function_device->input, ABS_MT_POSITION_Y, instanceData->oldY);
-		input_report_abs(function_device->input, ABS_MT_TRACKING_ID, 1);
+		input_report_abs(function_device->input, ABS_MT_PRESSURE, 0);
+		input_report_key(function_device->input, BTN_TOUCH, 0);
 		input_mt_sync(function_device->input);
 #endif
-
-		input_report_abs(function_device->input, ABS_X, instanceData->oldX);
-		input_report_abs(function_device->input, ABS_Y, instanceData->oldY);
-		instanceData->oldX = instanceData->oldY = 0;
 	}
 
 	FN_11_relreport(rmifninfo);
@@ -468,10 +451,11 @@
 	input_set_abs_params(function_device->input, ABS_TOOL_WIDTH, 0, 15, 0, 0);
 
 #ifdef CONFIG_SYNA_MULTI_TOUCH
-	input_set_abs_params(function_device->input, ABS_MT_TOUCH_MAJOR, 0, 15, 0, 0);
-	input_set_abs_params(function_device->input, ABS_MT_TOUCH_MINOR, 0, 15, 0, 0);
+	input_set_abs_params(function_device->input, ABS_MT_PRESSURE,
+							0, 15, 0, 0);
 	input_set_abs_params(function_device->input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
-	input_set_abs_params(function_device->input, ABS_MT_TRACKING_ID, 1, 10, 0, 0);
+	input_set_abs_params(function_device->input, ABS_MT_TRACKING_ID,
+							0, 10, 0, 0);
 	input_set_abs_params(function_device->input, ABS_MT_POSITION_X, xMin, xMax,
 		0, 0);
 	input_set_abs_params(function_device->input, ABS_MT_POSITION_Y, yMin, yMax,
@@ -536,8 +520,8 @@
 	set_bit(EV_ABS, function_device->input->evbit);
 	set_bit(EV_SYN, function_device->input->evbit);
 	set_bit(EV_KEY, function_device->input->evbit);
-    set_bit(BTN_MISC, function_device->input->keybit);
-    set_bit(KEY_OK, function_device->input->keybit);
+	set_bit(BTN_TOUCH, function_device->input->keybit);
+	set_bit(KEY_OK, function_device->input->keybit);
 
 	f11_set_abs_params(function_device);
 
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
index ca98754..57b11c9 100644
--- a/drivers/media/radio/radio-iris-transport.c
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -64,7 +64,7 @@
 			return;
 		}
 
-		rc = smd_read_from_cb(hsmd->fm_channel, (void *)buf, len);
+		rc = smd_read(hsmd->fm_channel, (void *)buf, len);
 
 		memcpy(skb_put(skb, len), buf, len);
 
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 5e70607..9a4a28c 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -648,6 +648,15 @@
 	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
 }
 
+static int hci_get_fm_trans_conf_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_TRANS_CONF_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
 static int hci_set_fm_recv_conf_req(struct radio_hci_dev *hdev,
 	unsigned long param)
 {
@@ -1474,6 +1483,10 @@
 			msecs_to_jiffies(RADIO_HCI_TIMEOUT));
 		break;
 
+	case HCI_FM_GET_TX_CONFIG:
+		ret = radio_hci_request(hdev, hci_get_fm_trans_conf_req, arg,
+			msecs_to_jiffies(RADIO_HCI_TIMEOUT));
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -1502,6 +1515,7 @@
 
 	if (status)
 		return;
+
 	radio_hci_req_complete(hdev, status);
 }
 
@@ -1531,6 +1545,19 @@
 	radio_hci_req_complete(hdev, rsp->status);
 }
 
+static void hci_cc_fm_trans_get_conf_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct hci_fm_get_trans_conf_rsp  *rsp = (void *)skb->data;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	if (rsp->status)
+		return;
+	memcpy((void *)&radio->trans_conf,  (void*)&rsp->trans_conf_rsp,
+			sizeof(rsp->trans_conf_rsp));
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
 static void hci_cc_fm_enable_rsp(struct radio_hci_dev *hdev,
 	struct sk_buff *skb)
 {
@@ -1863,6 +1890,9 @@
 		hci_cc_do_calibration_rsp(hdev, skb);
 		break;
 
+	case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_GET_TRANS_CONF_REQ):
+		hci_cc_fm_trans_get_conf_rsp(hdev, skb);
+		break;
 	default:
 		FMDERR("%s opcode 0x%x", hdev->name, opcode);
 		break;
@@ -2646,6 +2676,8 @@
 		retval = radio_hci_request(radio->fm_hdev,
 				hci_fm_tone_generator, arg,
 				msecs_to_jiffies(RADIO_HCI_TIMEOUT));
+		if (retval < 0)
+			FMDERR("Error while setting the tone %d", retval);
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
 		break;
@@ -2673,12 +2705,12 @@
 		case FM_RECV:
 			retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
 							 radio->fm_hdev);
-
-			radio->mode = FM_RECV;
-
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error while enabling RECV FM"
 							" %d\n", retval);
+				return retval;
+			}
+			radio->mode = FM_RECV;
 			radio->mute_mode.soft_mute = CTRL_ON;
 			retval = hci_set_fm_mute_mode(
 						&radio->mute_mode,
@@ -2715,10 +2747,14 @@
 			retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
 							 radio->fm_hdev);
 			radio->mode = FM_TRANS;
-
-			if (retval < 0)
+			if (retval < 0) {
 				FMDERR("Error while enabling TRANS FM"
 							" %d\n", retval);
+				return retval;
+			}
+			retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+			if (retval < 0)
+				FMDERR("get frequency failed %d\n", retval);
 			break;
 		case FM_OFF:
 			switch (radio->mode) {
@@ -2776,7 +2812,14 @@
 	case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
 		break;
 	case V4L2_CID_PRIVATE_IRIS_SPACING:
-		radio->recv_conf.ch_spacing = ctrl->value;
+		if (radio->mode == FM_RECV) {
+			radio->recv_conf.ch_spacing = ctrl->value;
+			retval = hci_set_fm_recv_conf(
+					&radio->recv_conf,
+						radio->fm_hdev);
+			if (retval < 0)
+				FMDERR("Error in setting channel spacing");
+		}
 		break;
 	case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
 		switch (radio->mode) {
@@ -2971,19 +3014,37 @@
 	if (tuner->index > 0)
 		return -EINVAL;
 
-	retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
-	if (retval < 0)
-		return retval;
+	if (radio->mode == FM_RECV) {
+		retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to Get station params");
+			return retval;
+		}
+		tuner->type = V4L2_TUNER_RADIO;
+		tuner->rangelow  =
+			radio->recv_conf.band_low_limit * TUNE_PARAM;
+		tuner->rangehigh =
+			radio->recv_conf.band_high_limit * TUNE_PARAM;
+		tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+		tuner->capability = V4L2_TUNER_CAP_LOW;
+		tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
+		tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
+		tuner->afc = 0;
+	} else if (radio->mode == FM_TRANS) {
+		retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("get Tx config failed %d\n", retval);
+			return retval;
+		} else {
+			tuner->type = V4L2_TUNER_RADIO;
+			tuner->rangelow =
+				radio->trans_conf.band_low_limit * TUNE_PARAM;
+			tuner->rangehigh =
+				radio->trans_conf.band_high_limit * TUNE_PARAM;
+		}
 
-	tuner->type = V4L2_TUNER_RADIO;
-	tuner->rangelow  = radio->recv_conf.band_low_limit * TUNE_PARAM;
-	tuner->rangehigh = radio->recv_conf.band_high_limit * TUNE_PARAM;
-	tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-	tuner->capability = V4L2_TUNER_CAP_LOW;
-	tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
-	tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
-	tuner->afc = 0;
-
+	} else
+		return -EINVAL;
 	return 0;
 }
 
@@ -3013,16 +3074,13 @@
 		if (retval < 0)
 			FMDERR(": set tuner failed with %d\n", retval);
 		return retval;
-	} else {
-		if (radio->mode == FM_TRANS) {
+	} else if (radio->mode == FM_TRANS) {
 			radio->trans_conf.band_low_limit =
 				tuner->rangelow / TUNE_PARAM;
 			radio->trans_conf.band_high_limit =
 				tuner->rangehigh / TUNE_PARAM;
-		} else {
-			  return -EINVAL;
-		}
-	}
+	} else
+		return -EINVAL;
 
 	return retval;
 }
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 5976424..d09f89f 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -118,6 +118,7 @@
 	int pi;
 	/*PS repeatcount for PS Tx */
 	int ps_repeatcount;
+	int enable_optimized_srch_alg;
 };
 
 /**************************************************************************
@@ -1162,6 +1163,169 @@
 	return 0;
 }
 
+static int optimized_search_algorithm(struct tavarua_device *radio,
+				int region)
+{
+	unsigned char adie_type_bahma;
+	int retval = 0;
+	unsigned int rdsMask = 0;
+	unsigned char value;
+
+	adie_type_bahma = is_bahama();
+
+	switch (region) {
+	case TAVARUA_REGION_US:
+	/*
+	Radio band for all the 200KHz channel-spaced regions
+	coming under EUROPE too, have been set as TAVARUA_REGION_US.
+	*/
+	FMDBG("%s: The region selected from APP is"
+		" : TAVARUA_REGION_US", __func__);
+	break;
+	case TAVARUA_REGION_EU:
+	/*
+	Radio band for all the 50KHz channel-spaced regions
+	coming under EUROPE, have been set as TAVARUA_REGION_EU.
+	*/
+	FMDBG("%s: The region selected from APP is : "
+		"TAVARUA_REGION_EU", __func__);
+	break;
+	case TAVARUA_REGION_JAPAN:
+	/*
+	Radio band for the 100KHz channel-spaced JAPAN region
+	has been set as TAVARUA_REGION_JAPAN.
+	*/
+	FMDBG("%s: The region selected from APP is"
+		" : TAVARUA_REGION_JAPAN", __func__);
+	break;
+	case TAVARUA_REGION_JAPAN_WIDE:
+	/*
+	Radio band for the 50KHz channel-spaced JAPAN WIDE region
+	has been set as TAVARUA_REGION_JAPAN_WIDE.
+	*/
+	FMDBG("%s: The region selected from APP is"
+		" : TAVARUA_REGION_JAPAN_WIDE", __func__);
+	break;
+	case TAVARUA_REGION_OTHER:
+	/*
+	Radio band for all the 100KHz channel-spaced regions
+	including those coming under EUROPE have been set as
+	TAVARUA_REGION_OTHER.
+	*/
+	FMDBG("%s: The region selected from APP is"
+		" : TAVARUA_REGION_OTHER", __func__);
+	break;
+	default:
+		pr_err("%s: Should not reach here.", __func__);
+		break;
+
+	}
+
+	/* Enable or Disable the 200KHz enforcer */
+	switch (region) {
+	case TAVARUA_REGION_US:
+	case TAVARUA_REGION_JAPAN:
+	case TAVARUA_REGION_OTHER:
+	/*
+	These are the 3 bands for which we need to enable the
+	200KHz enforcer in ADVCTL reg.
+	*/
+		if (adie_type_bahma) {
+			FMDBG("Adie type : Bahama\n");
+			FMDBG("%s: Enabling the 200KHz enforcer for"
+				" Region : %d", __func__, region);
+			/*Enable the 200KHz enforcer*/
+			retval = tavarua_read_registers(radio,
+				ADVCTRL, 1);
+			if (retval >= 0) {
+				rdsMask = radio->registers[ADVCTRL];
+				SET_REG_FIELD(rdsMask, ENF_SRCH200khz,
+					SRCH200KHZ_OFFSET, SRCH_MASK);
+				retval = tavarua_write_register(radio,
+					ADVCTRL, rdsMask);
+			} else
+				return retval;
+		} /* if Marimba do nothing */
+		break;
+	case TAVARUA_REGION_EU:
+	case TAVARUA_REGION_JAPAN_WIDE:
+	/*
+	These are the 2 bands for which we need to disable the
+	200KHz enforcer in ADVCTL reg.
+	Radio band for all the 50KHz channel-spaced regions
+	coming under EUROPE have been set as TAVARUA_REGION_EU.
+	*/
+		if (adie_type_bahma) {
+			FMDBG("Adie type : Bahama\n");
+			FMDBG("%s: Disabling the 200KHz enforcer for"
+				" Region : %d", __func__, region);
+			/*
+			Disable 200KHz enforcer for all 50 KHz
+			spaced regions.
+			*/
+			retval = tavarua_read_registers(radio,
+				ADVCTRL, 1);
+			if (retval >= 0) {
+				rdsMask = radio->registers[ADVCTRL];
+				SET_REG_FIELD(rdsMask, NO_SRCH200khz,
+					SRCH200KHZ_OFFSET, SRCH_MASK);
+				retval = tavarua_write_register(radio,
+					ADVCTRL, rdsMask);
+			} else
+				return retval;
+		} /* if Marimba do nothing */
+		break;
+	default:
+		FMDBG("%s: Defaulting in case of Enabling/Disabling"
+			"the 200KHz Enforcer", __func__);
+		break;
+	}
+
+	/* Set channel spacing */
+	switch (region) {
+	case TAVARUA_REGION_US:
+		if (adie_type_bahma) {
+			FMDBG("Adie type : Bahama\n");
+			/*
+			Configuring all 200KHZ spaced regions as 100KHz due to
+			change in the new Bahma FM SoC search algorithm.
+			*/
+			value = FM_CH_SPACE_100KHZ;
+		} else {
+			FMDBG("Adie type : Marimba\n");
+			value = FM_CH_SPACE_200KHZ;
+		}
+		break;
+	case TAVARUA_REGION_JAPAN:
+	case TAVARUA_REGION_OTHER:
+		if (adie_type_bahma) {
+			FMDBG("Adie type : Bahama\n");
+			FMDBG("%s: Configuring the channel-spacing as 50KHz"
+				"for the Region : %d", __func__, region);
+			/*
+			Configuring all 100KHZ spaced regions as 50KHz due to
+			change in the new Bahma FM SoC search algorithm.
+			*/
+			value = FM_CH_SPACE_50KHZ;
+		} else {
+			FMDBG("Adie type : Marimba\n");
+			value = FM_CH_SPACE_100KHZ;
+		}
+		break;
+	case TAVARUA_REGION_EU:
+	case TAVARUA_REGION_JAPAN_WIDE:
+		value = FM_CH_SPACE_50KHZ;
+		break;
+	default:
+		FMDBG("%s: Defualting in case of Channel-Spacing", __func__);
+		break;
+	}
+
+	SET_REG_FIELD(radio->registers[RDCTRL], value,
+		RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
+
+	return retval;
+}
 /*************************************************************************
  * fops/IOCTL helper functions
  ************************************************************************/
@@ -1255,14 +1419,11 @@
 	switch (region) {
 	case TAVARUA_REGION_US:
 	case TAVARUA_REGION_EU:
-	case TAVARUA_REGION_JAPAN_WIDE:
 		SET_REG_FIELD(radio->registers[RDCTRL], 0,
 			RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
 		break;
+	case TAVARUA_REGION_JAPAN_WIDE:
 	case TAVARUA_REGION_JAPAN:
-		SET_REG_FIELD(radio->registers[RDCTRL], 1,
-			RDCTRL_BAND_OFFSET, RDCTRL_BAND_MASK);
-		break;
 	default:
 		retval = sync_read_xfr(radio, RADIO_CONFIG, xfr_buf);
 		if (retval < 0) {
@@ -1286,85 +1447,6 @@
 		break;
 	}
 
-	/* Enable/Disable the 200KHz enforcer for respectiver regions */
-	switch (region) {
-	case TAVARUA_REGION_US:
-		if (adie_type_bahma) {
-			FMDBG("Adie type : Bahama\n");
-			/*Enable the 200KHz enforcer*/
-			retval = tavarua_read_registers(radio,
-				ADVCTRL, 1);
-			if (retval >= 0) {
-				rdsMask = radio->registers[ADVCTRL];
-				SET_REG_FIELD(rdsMask, ENF_SRCH200khz,
-					SRCH200KHZ_OFFSET, SRCH_MASK);
-				msleep(TAVARUA_DELAY);
-				retval = tavarua_write_register(radio,
-					ADVCTRL, rdsMask);
-			} else
-				return retval;
-		} /* if Marimba do nothing */
-		break;
-	case TAVARUA_REGION_EU:
-	case TAVARUA_REGION_JAPAN:
-	case TAVARUA_REGION_JAPAN_WIDE:
-	default:
-		if (adie_type_bahma) {
-			FMDBG("Adie type : Bahama\n");
-			/*
-			Disable 200KHz enforcer for all 100/50 KHz
-			spaced regions.
-			*/
-			retval = tavarua_read_registers(radio,
-				ADVCTRL, 1);
-			if (retval >= 0) {
-				rdsMask = radio->registers[ADVCTRL];
-				SET_REG_FIELD(rdsMask, NO_SRCH200khz,
-					SRCH200KHZ_OFFSET, SRCH_MASK);
-				msleep(TAVARUA_DELAY);
-				retval = tavarua_write_register(radio,
-					ADVCTRL, rdsMask);
-			} else
-				return retval;
-		} /* if Marimba do nothing */
-		break;
-	}
-
-	/* Set channel spacing */
-	switch (region) {
-	case TAVARUA_REGION_US:
-		if (adie_type_bahma) {
-			FMDBG("Adie type : Bahama\n");
-			/*
-			Configuring all 200KHZ spaced regions as
-			100KHz due to change in the new Bahma
-			FM SoC search algorithm.
-			*/
-			value = FM_CH_SPACE_100KHZ;
-		} else {
-			FMDBG("Adie type : Marimba\n");
-			value = FM_CH_SPACE_200KHZ;
-		}
-		break;
-	case TAVARUA_REGION_EU:
-	case TAVARUA_REGION_JAPAN:
-		value = FM_CH_SPACE_100KHZ;
-		break;
-	case TAVARUA_REGION_JAPAN_WIDE:
-		value = FM_CH_SPACE_50KHZ;
-		break;
-	default:
-		/*
-		Set the channel spacing as configured from
-		the upper layers.
-		*/
-		value = radio->region_params.spacing;
-		break;
-	}
-
-	SET_REG_FIELD(radio->registers[RDCTRL], value,
-		RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
-
 	/* Set De-emphasis and soft band range*/
 	switch (region) {
 	case TAVARUA_REGION_US:
@@ -1403,13 +1485,6 @@
 	if (retval < 0)
 		return retval;
 
-	FMDBG("RDCTRL: %x\n", radio->registers[RDCTRL]);
-	retval = tavarua_write_register(radio, RDCTRL,
-					radio->registers[RDCTRL]);
-	if (retval < 0) {
-		FMDERR("Could not set region in rdctrl\n");
-		return retval;
-	}
 
 	/* setting soft band */
 	switch (region) {
@@ -1430,6 +1505,101 @@
 		break;
 	}
 	radio->region_params.region = region;
+
+	/* Check for the FM Algorithm used */
+	if (radio->enable_optimized_srch_alg) {
+		FMDBG("Optimized Srch Algorithm!!!");
+		optimized_search_algorithm(radio, region);
+	} else {
+		FMDBG("Native Srch Algorithm!!!");
+		/* Enable/Disable the 200KHz enforcer */
+		switch (region) {
+		case TAVARUA_REGION_US:
+			if (adie_type_bahma) {
+				FMDBG("Adie type : Bahama\n");
+				/*Enable the 200KHz enforcer*/
+				retval = tavarua_read_registers(radio,
+					ADVCTRL, 1);
+				if (retval >= 0) {
+					rdsMask = radio->registers[ADVCTRL];
+					SET_REG_FIELD(rdsMask, ENF_SRCH200khz,
+						SRCH200KHZ_OFFSET, SRCH_MASK);
+					retval = tavarua_write_register(radio,
+						ADVCTRL, rdsMask);
+				} else
+					return retval;
+			} /* if Marimba do nothing */
+			break;
+		case TAVARUA_REGION_EU:
+		case TAVARUA_REGION_JAPAN:
+		case TAVARUA_REGION_JAPAN_WIDE:
+		default:
+			if (adie_type_bahma) {
+				FMDBG("Adie type : Bahama\n");
+				/*
+				Disable 200KHz enforcer for all 100/50 KHz
+				spaced regions.
+				*/
+				retval = tavarua_read_registers(radio,
+					ADVCTRL, 1);
+				if (retval >= 0) {
+					rdsMask = radio->registers[ADVCTRL];
+					SET_REG_FIELD(rdsMask, NO_SRCH200khz,
+						SRCH200KHZ_OFFSET, SRCH_MASK);
+					retval = tavarua_write_register(radio,
+						ADVCTRL, rdsMask);
+				} else
+					return retval;
+			} /* if Marimba do nothing */
+			break;
+		}
+
+		/* Set channel spacing */
+		switch (region) {
+		case TAVARUA_REGION_US:
+			if (adie_type_bahma) {
+				FMDBG("Adie type : Bahama\n");
+				/*
+				Configuring all 200KHZ spaced regions as
+				100KHz due to change in the new Bahma
+				FM SoC search algorithm.
+				*/
+				value = FM_CH_SPACE_100KHZ;
+			} else {
+				FMDBG("Adie type : Marimba\n");
+				value = FM_CH_SPACE_200KHZ;
+			}
+			break;
+		case TAVARUA_REGION_JAPAN:
+			value = FM_CH_SPACE_100KHZ;
+			break;
+		case TAVARUA_REGION_EU:
+		case TAVARUA_REGION_JAPAN_WIDE:
+			value = FM_CH_SPACE_50KHZ;
+			break;
+		default:
+			/*
+			Set the channel spacing as configured from
+			the upper layers.
+			*/
+			value = radio->region_params.spacing;
+			break;
+		}
+
+		SET_REG_FIELD(radio->registers[RDCTRL], value,
+			RDCTRL_CHSPACE_OFFSET, RDCTRL_CHSPACE_MASK);
+
+	}
+
+	/* Write the config values into RDCTL register */
+	FMDBG("RDCTRL: %x\n", radio->registers[RDCTRL]);
+	retval = tavarua_write_register(radio, RDCTRL,
+					radio->registers[RDCTRL]);
+	if (retval < 0) {
+		FMDERR("Could not set region in rdctrl\n");
+		return retval;
+	}
+
 	return retval;
 }
 
@@ -2839,6 +3009,11 @@
 			}
 		}
 		break;
+	case V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM:
+		radio->enable_optimized_srch_alg = ctrl->value;
+		FMDBG("V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM : %d",
+			radio->enable_optimized_srch_alg);
+		break;
 	case V4L2_CID_PRIVATE_TAVARUA_REGION:
 		retval = tavarua_set_region(radio, ctrl->value);
 		break;
@@ -3658,7 +3833,7 @@
 	printk(KERN_INFO DRIVER_NAME "%s: radio suspend\n\n", __func__);
 	if (radio) {
 		users = atomic_read(&radio->users);
-		if (users) {
+		if (!users) {
 			retval = tavarua_disable_interrupts(radio);
 			if (retval < 0) {
 				printk(KERN_INFO DRIVER_NAME
@@ -3690,7 +3865,7 @@
 	if (radio) {
 		users = atomic_read(&radio->users);
 
-		if (users) {
+		if (!users) {
 			retval = tavarua_setup_interrupts(radio,
 			(radio->registers[RDCTRL] & 0x03));
 			if (retval < 0) {
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index fb809c9..7a0ee4d 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -97,6 +97,7 @@
 	val |= 0x1 << 10;
 	val |= 0x1 << 11;
 	val |= 0x1 << 12;
+	val |= 0x1 << 13;
 	val |= 0x1 << 28;
 	msm_io_w(val, csidbase + CSID_CORE_CTRL_ADDR);
 
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index b62ec84..109b3dd 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -79,7 +79,7 @@
 	msm_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
 
 	for (i = 0; i < csiphy_params->lane_cnt; i++) {
-		msm_io_w(0x10, csiphybase + MIPI_CSIPHY_LNn_CFG1_ADDR + 0x40*i);
+		msm_io_w(0x00, csiphybase + MIPI_CSIPHY_LNn_CFG1_ADDR + 0x40*i);
 		msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
 		msm_io_w(csiphy_params->settle_cnt,
 			csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*i);
diff --git a/drivers/media/video/msm/flash.c b/drivers/media/video/msm/flash.c
index f1a24cc..6985f3c 100644
--- a/drivers/media/video/msm/flash.c
+++ b/drivers/media/video/msm/flash.c
@@ -293,6 +293,7 @@
 		if (sc628a_client) {
 			gpio_set_value_cansleep(external->led_en, 1);
 			gpio_set_value_cansleep(external->led_flash_en, 1);
+			usleep_range(2000, 3000);
 		}
 		rc = sc628a_i2c_write_b_flash(0x02, 0x06);
 		break;
@@ -301,6 +302,7 @@
 		if (sc628a_client) {
 			gpio_set_value_cansleep(external->led_en, 1);
 			gpio_set_value_cansleep(external->led_flash_en, 1);
+			usleep_range(2000, 3000);
 		}
 		rc = sc628a_i2c_write_b_flash(0x02, 0x49);
 		break;
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index 019d6e1..23db5f6b 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -138,34 +138,155 @@
 	return rc;
 }
 
+int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t mask,
+	enum msm_camera_i2c_data_type data_type, uint16_t set_mask)
+{
+	int32_t rc;
+	uint16_t reg_data;
+
+	rc = msm_camera_i2c_read(client, addr, &reg_data, data_type);
+	if (rc < 0) {
+		S_I2C_DBG("%s read fail\n", __func__);
+		return rc;
+	}
+	S_I2C_DBG("%s addr: 0x%x data: 0x%x setmask: 0x%x\n",
+			__func__, addr, reg_data, mask);
+
+	if (set_mask)
+		reg_data |= mask;
+	else
+		reg_data &= ~mask;
+	S_I2C_DBG("%s write: 0x%x\n", __func__, reg_data);
+
+	rc = msm_camera_i2c_write(client, addr, reg_data, data_type);
+	if (rc < 0)
+		S_I2C_DBG("%s write fail\n", __func__);
+
+	return rc;
+}
+
+int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EIO;
+	uint16_t reg_data = 0;
+	int data_len = 0;
+	switch (data_type) {
+	case MSM_CAMERA_I2C_BYTE_DATA:
+	case MSM_CAMERA_I2C_WORD_DATA:
+		data_len = data_type;
+		break;
+	case MSM_CAMERA_I2C_SET_BYTE_MASK:
+	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+		data_len = MSM_CAMERA_I2C_BYTE_DATA;
+		break;
+	case MSM_CAMERA_I2C_SET_WORD_MASK:
+	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+		data_len = MSM_CAMERA_I2C_WORD_DATA;
+		break;
+	default:
+		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+		break;
+	}
+
+	rc = msm_camera_i2c_read(client,
+		addr, &reg_data, data_len);
+	if (rc < 0)
+		return rc;
+
+	rc = 0;
+	switch (data_type) {
+	case MSM_CAMERA_I2C_BYTE_DATA:
+	case MSM_CAMERA_I2C_WORD_DATA:
+		if (data == reg_data)
+			return rc;
+		break;
+	case MSM_CAMERA_I2C_SET_BYTE_MASK:
+	case MSM_CAMERA_I2C_SET_WORD_MASK:
+		if ((reg_data & data) == data)
+			return rc;
+		break;
+	case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+	case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+		if (!(reg_data & data))
+			return rc;
+		break;
+	default:
+		pr_err("%s: Unsupport data type: %d\n", __func__, data_type);
+		break;
+	}
+
+	S_I2C_DBG("%s: Register and data does not match\n", __func__);
+	rc = 1;
+	return rc;
+}
+
+int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EIO;
+	int i;
+	S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
+		__func__, addr, data, data_type);
+
+	for (i = 0; i < 20; i++) {
+		rc = msm_camera_i2c_compare(client,
+			addr, data, data_type);
+		if (rc == 0 || rc < 0)
+			break;
+		usleep_range(10000, 11000);
+	}
+	return rc;
+}
+
 int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint8_t size,
+	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int i;
 	int32_t rc = -EFAULT;
 	for (i = 0; i < size; i++) {
-		rc = msm_camera_i2c_write(
-			client,
-			reg_conf_tbl->reg_addr,
-			reg_conf_tbl->reg_data, data_type);
-		if (rc < 0)
-			break;
-		reg_conf_tbl++;
-	}
-	return rc;
-}
+		enum msm_camera_i2c_data_type dt;
+		if (reg_conf_tbl->dt == 0)
+			dt = data_type;
+		else
+			dt = reg_conf_tbl->dt;
 
-int32_t msm_camera_i2c_write_dt_tbl(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_dt_conf *reg_conf_tbl, uint16_t size)
-{
-	int i;
-	int32_t rc = -EFAULT;
-	for (i = 0; i < size; i++) {
-		rc = msm_camera_i2c_write(
-			client,
-			reg_conf_tbl->reg_addr,
-			reg_conf_tbl->reg_data, reg_conf_tbl->dt);
+		switch (dt) {
+		case MSM_CAMERA_I2C_BYTE_DATA:
+		case MSM_CAMERA_I2C_WORD_DATA:
+			rc = msm_camera_i2c_write(
+				client,
+				reg_conf_tbl->reg_addr,
+				reg_conf_tbl->reg_data, dt);
+			break;
+		case MSM_CAMERA_I2C_SET_BYTE_MASK:
+			rc = msm_camera_i2c_set_mask(client,
+				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+				MSM_CAMERA_I2C_BYTE_DATA, 1);
+			break;
+		case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+			rc = msm_camera_i2c_set_mask(client,
+				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+				MSM_CAMERA_I2C_BYTE_DATA, 0);
+			break;
+		case MSM_CAMERA_I2C_SET_WORD_MASK:
+			rc = msm_camera_i2c_set_mask(client,
+				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+				MSM_CAMERA_I2C_WORD_DATA, 1);
+			break;
+		case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+			rc = msm_camera_i2c_set_mask(client,
+				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
+				MSM_CAMERA_I2C_WORD_DATA, 0);
+			break;
+		default:
+			pr_err("%s: Unsupport data type: %d\n", __func__, dt);
+			break;
+		}
 		if (rc < 0)
 			break;
 		reg_conf_tbl++;
@@ -202,7 +323,7 @@
 	else
 		*data = buf[0] << 8 | buf[1];
 
-	S_I2C_DBG("%s addr = 0x%x data: 0x%x", __func__, addr, *data);
+	S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data);
 	return rc;
 }
 
@@ -243,15 +364,16 @@
 			struct msm_camera_i2c_conf_array *array, uint16_t index)
 {
 	int32_t rc;
-	if (array[index].data_type != MSM_CAMERA_I2C_HYBRID_DATA) {
-		rc = msm_camera_i2c_write_tbl(client,
-			(struct msm_camera_i2c_reg_conf *) array[index].conf,
-			array[index].size, array[index].data_type);
-	} else {
-		rc = msm_camera_i2c_write_dt_tbl(client,
-			(struct msm_camera_i2c_reg_dt_conf *) array[index].conf,
-			array[index].size);
-	}
+	if (array[index].pre_process != NULL)
+		array[index].pre_process();
+
+	rc = msm_camera_i2c_write_tbl(client,
+		(struct msm_camera_i2c_reg_conf *) array[index].conf,
+		array[index].size, array[index].data_type);
+
+	if (array[index].post_process != NULL)
+		array[index].post_process();
+
 	if (array[index].delay > 20)
 		msleep(array[index].delay);
 	else
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 201cd03..05b3960 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -35,28 +35,28 @@
 	enum msm_camera_i2c_reg_addr_type addr_type;
 };
 
-struct msm_camera_i2c_reg_conf {
-	uint16_t reg_addr;
-	uint16_t reg_data;
-};
-
 enum msm_camera_i2c_data_type {
 	MSM_CAMERA_I2C_BYTE_DATA = 1,
 	MSM_CAMERA_I2C_WORD_DATA,
-	MSM_CAMERA_I2C_HYBRID_DATA,
+	MSM_CAMERA_I2C_SET_BYTE_MASK,
+	MSM_CAMERA_I2C_UNSET_BYTE_MASK,
+	MSM_CAMERA_I2C_SET_WORD_MASK,
+	MSM_CAMERA_I2C_UNSET_WORD_MASK,
 };
 
-struct msm_camera_i2c_reg_dt_conf {
+struct msm_camera_i2c_reg_conf {
 	uint16_t reg_addr;
 	uint16_t reg_data;
 	enum msm_camera_i2c_data_type dt;
 };
 
 struct msm_camera_i2c_conf_array {
-	void *conf;
+	struct msm_camera_i2c_reg_conf *conf;
 	uint16_t size;
 	uint16_t delay;
 	enum msm_camera_i2c_data_type data_type;
+	int (*pre_process) (void);
+	int (*post_process) (void);
 };
 
 int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *client,
@@ -79,12 +79,21 @@
 int32_t msm_camera_i2c_write_seq(struct msm_camera_i2c_client *client,
 	uint16_t addr, uint8_t *data, uint16_t num_byte);
 
-int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint8_t size,
+int32_t msm_camera_i2c_set_mask(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t mask,
+	enum msm_camera_i2c_data_type data_type, uint16_t flag);
+
+int32_t msm_camera_i2c_compare(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type);
 
-int32_t msm_camera_i2c_write_dt_tbl(struct msm_camera_i2c_client *client,
-	struct msm_camera_i2c_reg_dt_conf *reg_conf_tbl, uint16_t size);
+int32_t msm_camera_i2c_poll(struct msm_camera_i2c_client *client,
+	uint16_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
 	struct msm_camera_i2c_conf_array *array, uint16_t index);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index f11e43f..3e3b9c8 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -485,6 +485,10 @@
 int msm_mctl_pp_done(
 	struct msm_cam_media_controller *p_mctl,
 	void __user *arg);
+int msm_mctl_pp_divert_done(
+	struct msm_cam_media_controller *p_mctl,
+	void __user *arg);
+
 #endif /* __KERNEL__ */
 
 #endif /* _MSM_H */
diff --git a/drivers/media/video/msm/msm_io_7x27a.c b/drivers/media/video/msm/msm_io_7x27a.c
index b1f9532..7a83721 100644
--- a/drivers/media/video/msm/msm_io_7x27a.c
+++ b/drivers/media/video/msm/msm_io_7x27a.c
@@ -288,11 +288,6 @@
 	clk_set_rate(clk, rate);
 }
 
-void msm_camio_clk_set_min_rate(struct clk *clk, int rate)
-{
-	clk_set_min_rate(clk, rate);
-}
-
 static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
 {
 	uint32_t irq;
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index 1293c7b..ec18a93 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -346,7 +346,7 @@
 	case CAMIO_JPEG_CLK:
 		camio_jpeg_clk =
 		clk = clk_get(NULL, "ijpeg_clk");
-		clk_set_min_rate(clk, 144000000);
+		clk_set_rate(clk, 153600000);
 		break;
 
 	case CAMIO_JPEG_PCLK:
@@ -414,11 +414,6 @@
 	clk_set_rate(clk, rate);
 }
 
-void msm_camio_clk_set_min_rate(struct clk *clk, int rate)
-{
-	clk_set_min_rate(clk, rate);
-}
-
 int msm_camio_jpeg_clk_disable(void)
 {
 	int rc = 0;
diff --git a/drivers/media/video/msm/msm_io_8x60.c b/drivers/media/video/msm/msm_io_8x60.c
index 2262aa4..9620d8b 100644
--- a/drivers/media/video/msm/msm_io_8x60.c
+++ b/drivers/media/video/msm/msm_io_8x60.c
@@ -344,7 +344,8 @@
 	case CAMIO_VPE_CLK:
 		camio_vpe_clk =
 		clk = clk_get(NULL, "vpe_clk");
-		msm_camio_clk_set_min_rate(camio_vpe_clk, vpe_clk_rate);
+		vpe_clk_rate = clk_round_rate(camio_vpe_clk, vpe_clk_rate);
+		clk_set_rate(camio_vpe_clk, vpe_clk_rate);
 		break;
 
 	case CAMIO_VPE_PCLK:
@@ -457,11 +458,6 @@
 	clk_set_rate(clk, rate);
 }
 
-void msm_camio_clk_set_min_rate(struct clk *clk, int rate)
-{
-	clk_set_min_rate(clk, rate);
-}
-
 static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
 {
 	uint32_t irq;
diff --git a/drivers/media/video/msm/msm_io_vfe31.c b/drivers/media/video/msm/msm_io_vfe31.c
index f770ce9..91dbc8f 100644
--- a/drivers/media/video/msm/msm_io_vfe31.c
+++ b/drivers/media/video/msm/msm_io_vfe31.c
@@ -117,6 +117,7 @@
 static struct resource *camifpadio, *csiio;
 void __iomem *camifpadbase, *csibase;
 static uint32_t vpe_clk_rate;
+static uint32_t jpeg_clk_rate;
 
 static struct regulator_bulk_data regs[] = {
 	{ .supply = "gp2",  .min_uV = 2600000, .max_uV = 2600000 },
@@ -317,7 +318,8 @@
 	case CAMIO_JPEG_CLK:
 		camio_jpeg_clk =
 		clk = clk_get(NULL, "jpeg_clk");
-		clk_set_min_rate(clk, 144000000);
+		jpeg_clk_rate = clk_round_rate(clk, 144000000);
+		clk_set_rate(clk, jpeg_clk_rate);
 		break;
 	case CAMIO_JPEG_PCLK:
 		camio_jpeg_pclk =
@@ -326,7 +328,8 @@
 	case CAMIO_VPE_CLK:
 		camio_vpe_clk =
 		clk = clk_get(NULL, "vpe_clk");
-		msm_camio_clk_set_min_rate(clk, vpe_clk_rate);
+		vpe_clk_rate = clk_round_rate(clk, vpe_clk_rate);
+		clk_set_rate(clk, vpe_clk_rate);
 		break;
 	default:
 		break;
@@ -420,11 +423,6 @@
 	clk_set_rate(clk, rate);
 }
 
-void msm_camio_clk_set_min_rate(struct clk *clk, int rate)
-{
-	clk_set_min_rate(clk, rate);
-}
-
 static irqreturn_t msm_io_csi_irq(int irq_num, void *data)
 {
 	uint32_t irq;
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index e4d4f27..0a1516b 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -268,6 +268,10 @@
 	struct msm_sync *sync =
 		(struct msm_sync *)v4l2_get_subdev_hostdata(sd);
 	struct msm_vpe_resp *vdata = (struct msm_vpe_resp *)arg;
+	if (sync == NULL) {
+		pr_err("%s: VPE subdev hostdata not set\n", __func__);
+		return -EINVAL;
+	}
 
 	msm_mctl_pp_notify(&sync->pcam_sync->mctl,
 		(struct msm_mctl_pp_frame_info *)vdata->extdata);
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index a3cf004..73fd383 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -299,6 +299,9 @@
 	case MSM_CAM_IOCTL_PICT_PP:
 		rc = msm_mctl_set_pp_key(p_mctl, (void __user *)arg);
 		break;
+	case MSM_CAM_IOCTL_PICT_PP_DIVERT_DONE:
+		rc = msm_mctl_pp_divert_done(p_mctl, (void __user *)arg);
+		break;
 	case MSM_CAM_IOCTL_PICT_PP_DONE:
 		rc = msm_mctl_pp_done(p_mctl, (void __user *)arg);
 		break;
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index c7c7cf6..7a0cc02 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -97,8 +97,15 @@
 	if (buf->state == MSM_BUFFER_STATE_INITIALIZED)
 		return rc;
 
-	buf_type = (vb->num_planes == 1) ? VIDEOBUF2_SINGLE_PLANE
-					: VIDEOBUF2_MULTIPLE_PLANES;
+	if (pcam_inst->plane_info.buffer_type ==
+		V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		buf_type = VIDEOBUF2_MULTIPLE_PLANES;
+	else if (pcam_inst->plane_info.buffer_type ==
+		V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		buf_type = VIDEOBUF2_SINGLE_PLANE;
+	else
+		return -EINVAL;
+
 	if (buf_type == VIDEOBUF2_SINGLE_PLANE) {
 		offset.sp_off.y_off = pcam_inst->plane_info.sp_y_offset;
 		offset.sp_off.cbcr_off =
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index 8236dae..77f963c 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -49,7 +49,7 @@
 		return -ENOMEM;
 	}
 	D("%s: msm_cam_evt_divert_frame=%d",
-		   __func__, sizeof(struct msm_cam_evt_divert_frame));
+		__func__, sizeof(struct msm_cam_evt_divert_frame));
 	memset(&v4l2_evt, 0, sizeof(v4l2_evt));
 	v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
 			MSM_CAM_RESP_DIV_FRAME_EVT_MSG;
@@ -82,7 +82,7 @@
 		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
 		if (p_mctl->pp_info.pp_key & pp_key)
 			*pp_divert_type = OUTPUT_TYPE_P;
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_P)
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_P)
 			*pp_type = OUTPUT_TYPE_P;
 		break;
 	case VFE_MSG_OUTPUT_S:
@@ -90,15 +90,15 @@
 		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
 		if (p_mctl->pp_info.pp_key & pp_key)
 			*pp_divert_type = OUTPUT_TYPE_S;
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_S)
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_S)
 			*pp_type = OUTPUT_TYPE_P;
 		break;
 	case VFE_MSG_OUTPUT_V:
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_V)
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_V)
 			*pp_type = OUTPUT_TYPE_V;
 		break;
 	case VFE_MSG_OUTPUT_T:
-		if (p_mctl->pp_info.pp_ctrl.pp_msg_type == OUTPUT_TYPE_T)
+		if (p_mctl->pp_info.pp_ctrl.pp_msg_type & OUTPUT_TYPE_T)
 			*pp_type = OUTPUT_TYPE_T;
 		break;
 	default:
@@ -142,10 +142,8 @@
 	div.op_mode    = pcam_inst->pcam->op_mode;
 	div.inst_idx   = pcam_inst->my_index;
 	div.node_idx   = pcam_inst->pcam->vnode_id;
-	p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
-	if (p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] == 0)
-		p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
-	div.frame.frame_id   =
+	p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] = frame_id;
+	div.frame.frame_id =
 		p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
 	div.frame.handle = (uint32_t)vb;
 	msm_mctl_gettimeofday(&div.frame.timestamp);
@@ -160,7 +158,7 @@
 		/* This buffer contains only 1 plane. Use the
 		 * single planar structure to store the info.*/
 		div.frame.num_planes	= 1;
-		div.frame.sp.phy_addr   =
+		div.frame.sp.phy_addr	=
 			videobuf2_to_pmem_contig(&vb->vidbuf, 0);
 		div.frame.sp.addr_offset = mem->addr_offset;
 		div.frame.sp.y_off      = 0;
@@ -582,28 +580,17 @@
 				sizeof(divert_pp)))
 			return -EFAULT;
 		D("%s: PP_PATH, path=%d",
-			   __func__, divert_pp.path);
+			__func__, divert_pp.path);
 		spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
-		p_mctl->pp_info.pp_ctrl.pp_msg_type = divert_pp.path;
+		if (divert_pp.enable)
+			p_mctl->pp_info.pp_ctrl.pp_msg_type |= divert_pp.path;
+		else
+			p_mctl->pp_info.pp_ctrl.pp_msg_type &= ~divert_pp.path;
 		spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
-		D("%s: pp path = %d", __func__,
-			   p_mctl->pp_info.pp_ctrl.pp_msg_type);
+		D("%s: pp path = 0x%x", __func__,
+			p_mctl->pp_info.pp_ctrl.pp_msg_type);
 		break;
 	}
-	case MCTL_CMD_DIVERT_FRAME_PP_DONE: {
-		struct msm_frame_buffer *buf = NULL;
-		if (copy_from_user(&pp_buffer, pp_cmd->value,
-				sizeof(pp_buffer)))
-			return -EFAULT;
-		buf = (struct msm_frame_buffer *)pp_buffer.buf_handle;
-		msg_type = msm_mctl_pp_path_to_msg_type(
-						pp_buffer.path);
-		if (msm_mctl_buf_del(p_mctl, msg_type, buf) == 0) {
-			vb2_buffer_done(&buf->vidbuf,
-				VB2_BUF_STATE_DONE);
-		}
-	}
-	break;
 	default:
 		rc = -EPERM;
 	break;
@@ -843,7 +830,7 @@
 		memset(&p_mctl->pp_info.div_frame[image_mode],
 			0, sizeof(buf));
 		if (p_mctl->pp_info.cur_frame_id[image_mode] !=
-					  frame.frame_id) {
+					frame.frame_id) {
 			/* dirty frame. should not pass to app */
 			dirty = 1;
 		}
@@ -862,3 +849,49 @@
 	return rc;
 }
 
+int msm_mctl_pp_divert_done(
+	struct msm_cam_media_controller *p_mctl,
+	void __user *arg)
+{
+	struct msm_pp_frame frame;
+	int msg_type, image_mode, rc = 0;
+	int dirty = 0;
+	struct msm_free_buf buf;
+	unsigned long flags;
+
+	if (copy_from_user(&frame, arg, sizeof(frame)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+	switch (frame.path) {
+	case OUTPUT_TYPE_P:
+		msg_type = VFE_MSG_OUTPUT_P;
+		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+		break;
+	case OUTPUT_TYPE_S:
+		msg_type = VFE_MSG_OUTPUT_S;
+		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+		break;
+	case OUTPUT_TYPE_V:
+		msg_type = VFE_MSG_OUTPUT_V;
+		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
+		break;
+	case OUTPUT_TYPE_T:
+	default:
+		rc = -EFAULT;
+		goto err;
+	}
+	if (frame.num_planes > 1)
+		buf.ch_paddr[0] = frame.mp[0].phy_addr;
+	else
+		buf.ch_paddr[0] = frame.sp.phy_addr;
+	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+	/* here buf.addr is phy_addr */
+	rc = msm_mctl_buf_done_pp(p_mctl, msg_type, &buf, dirty);
+	return rc;
+err:
+	spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+	return rc;
+}
+
+
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index c5cc55c..d34d5b1 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -1461,6 +1461,45 @@
 		cmdp_local, (vfe32_cmd[cmd->id].length));
 		}
 		break;
+	case VFE_CMD_CHROMA_SUP_UPDATE:
+	case VFE_CMD_CHROMA_SUP_CFG:{
+		cmdp = kmalloc(cmd->length, GFP_ATOMIC);
+		if (!cmdp) {
+			rc = -ENOMEM;
+			goto proc_general_done;
+		}
+		if (copy_from_user(cmdp,
+			(void __user *)(cmd->value),
+			cmd->length)) {
+			rc = -EFAULT;
+			goto proc_general_done;
+		}
+		cmdp_local = cmdp;
+		msm_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF,
+			cmdp_local, 4);
+
+		cmdp_local += 1;
+		new_val = *cmdp_local;
+		/* Incrementing with 4 so as to point to the 2nd Register as
+		 * the 2nd register has the mce_enable bit
+		 */
+		old_val = msm_io_r(vfe32_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 4);
+		old_val &= ~MCE_EN_MASK;
+		new_val = new_val | old_val;
+		msm_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 4,
+			&new_val, 4);
+		cmdp_local += 1;
+
+		old_val = msm_io_r(vfe32_ctrl->vfebase +
+			V32_CHROMA_SUP_OFF + 8);
+		new_val = *cmdp_local;
+		old_val &= ~MCE_Q_K_MASK;
+		new_val = new_val | old_val;
+		msm_io_memcpy(vfe32_ctrl->vfebase + V32_CHROMA_SUP_OFF + 8,
+			&new_val, 4);
+		}
+		break;
 	case VFE_CMD_BLACK_LEVEL_CFG:
 		rc = -EFAULT;
 		goto proc_general_done;
@@ -2223,17 +2262,17 @@
 
 		CDBG("%s: PCA Rolloff Ram0\n", __func__);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE * 2; i++) {
-			temp2 = (i == (V33_PCA_ROLL_OFF_TABLE_SIZE - 1));
+			temp2 = (i == (V33_PCA_ROLL_OFF_TABLE_SIZE));
 			if (old_val && temp2)
 				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1);
 			else if (!old_val && temp2)
 				vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0);
 
+			*cmdp_local = msm_io_r(vfe32_ctrl->vfebase +
+				VFE33_DMI_DATA_LO);
 			*(cmdp_local + 1) =
 				msm_io_r(vfe32_ctrl->vfebase +
 				VFE33_DMI_DATA_HI);
-			*cmdp_local = msm_io_r(vfe32_ctrl->vfebase +
-				VFE33_DMI_DATA_LO);
 			CDBG("%s: %08x%08x\n", __func__,
 				*(cmdp_local + 1), *cmdp_local);
 			cmdp_local += 2;
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 658f911..2f693ea 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -668,6 +668,7 @@
 		atomic_set(&vpe_init_done, 0);
 		return rc;
 	}
+	v4l2_set_subdev_hostdata(sd, data);
 	spin_lock_init(&vpe_ctrl->lock);
 	CDBG("%s:end", __func__);
 	return rc;
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index 2923e5d..f721441 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -51,8 +51,8 @@
 	{0x0383, 0x03}, /*x_odd_inc*/
 	{0x0385, 0x01}, /*y_even_inc*/
 	{0x0387, 0x03}, /*y_odd_inc*/
-	{0x3001, 0x00}, /*hmodeadd*/
-	{0x3016, 0x06}, /*vmodeadd*/
+	{0x3001, 0x80}, /*hmodeadd*/
+	{0x3016, 0x16}, /*vmodeadd*/
 	{0x3069, 0x24}, /*vapplinepos_start*/
 	{0x306b, 0x53}, /*vapplinepos_end*/
 	{0x3086, 0x00}, /*shutter*/
@@ -164,7 +164,7 @@
 		.frame_length_lines = 0x62D,
 		.vt_pixel_clk = 216000000,
 		.op_pixel_clk = 216000000,
-		.binning_factor = 1,
+		.binning_factor = 2,
 	},
 };
 
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 51d2224..373aaf7 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -39,9 +39,11 @@
 
 #define PM8921_VERSION_MASK	0xFFF0
 #define PM8921_VERSION_VALUE	0x06F0
+#define PM8922_VERSION_VALUE	0x0AF0
 #define PM8921_REVISION_MASK	0x000F
 
 #define REG_PM8921_PON_CNTRL_3	0x01D
+#define REG_PM8921_PON_CNTRL_4	0x01E
 #define PM8921_RESTART_REASON_MASK	0x07
 
 #define SINGLE_IRQ_RESOURCE(_name, _irq) \
@@ -109,6 +111,9 @@
 
 	if ((pmic->rev_registers & PM8921_VERSION_MASK) == PM8921_VERSION_VALUE)
 		version = PM8XXX_VERSION_8921;
+	else if ((pmic->rev_registers & PM8921_VERSION_MASK)
+			== PM8922_VERSION_VALUE)
+		version = PM8XXX_VERSION_8922;
 
 	return version;
 }
@@ -365,8 +370,11 @@
 	int ret = 0, irq_base = 0;
 	struct pm_irq_chip *irq_chip;
 	static struct mfd_cell *mfd_regulators;
+	enum pm8xxx_version version;
 	int i;
 
+	version = pm8xxx_get_version(pmic->dev);
+
 	if (pdata->irq_pdata) {
 		pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS;
 		pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE;
@@ -619,6 +627,13 @@
 	[PM8XXX_REVISION_8921_3p0]	= "3.0",
 };
 
+static const char * const pm8922_rev_names[] = {
+	[PM8XXX_REVISION_8922_TEST]	= "test",
+	[PM8XXX_REVISION_8922_1p0]	= "1.0",
+	[PM8XXX_REVISION_8922_1p1]	= "1.1",
+	[PM8XXX_REVISION_8922_2p0]	= "2.0",
+};
+
 static int __devinit pm8921_probe(struct platform_device *pdev)
 {
 	const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
@@ -665,13 +680,18 @@
 
 	/* Print out human readable version and revision names. */
 	version = pm8xxx_get_version(pmic->dev);
+	revision = pm8xxx_get_revision(pmic->dev);
 	if (version == PM8XXX_VERSION_8921) {
-		revision = pm8xxx_get_revision(pmic->dev);
 		if (revision >= 0 && revision < ARRAY_SIZE(pm8921_rev_names))
 			revision_name = pm8921_rev_names[revision];
 		pr_info("PMIC version: PM8921 rev %s\n", revision_name);
+	} else if (version == PM8XXX_VERSION_8922) {
+		if (revision >= 0 && revision < ARRAY_SIZE(pm8922_rev_names))
+			revision_name = pm8922_rev_names[revision];
+		pr_info("PMIC version: PM8922 rev %s\n", revision_name);
 	} else {
-		WARN_ON(version != PM8XXX_VERSION_8921);
+		WARN_ON(version != PM8XXX_VERSION_8921
+			&& version != PM8XXX_VERSION_8922);
 	}
 
 	/* Log human readable restart reason */
@@ -683,6 +703,14 @@
 	val &= PM8921_RESTART_REASON_MASK;
 	pr_info("PMIC Restart Reason: %s\n", pm8921_restart_reason[val]);
 
+	/* Set power-on-reset to 3 seconds */
+	val = 0xBB;
+	rc = msm_ssbi_write(pdev->dev.parent, REG_PM8921_PON_CNTRL_4, &val, 1);
+	if (rc) {
+		pr_err("Cannot write power-on-reset rc=%d\n", rc);
+		goto err;
+	}
+
 	rc = pm8921_add_subdevices(pdata, pmic);
 	if (rc) {
 		pr_err("Cannot add subdevices rc=%d\n", rc);
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index 5b4f7e3..f65a183 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -1360,7 +1360,8 @@
 	version = pm8xxx_get_version(chip->dev->parent);
 
 	if (version == PM8XXX_VERSION_8921 ||
-			version == PM8XXX_VERSION_8058) {
+			version == PM8XXX_VERSION_8058 ||
+			version == PM8XXX_VERSION_8922) {
 		chip->is_lpg_supported = 1;
 	}
 	if (chip->is_lpg_supported) {
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 79f78bf..385f8ff 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -66,3 +66,4 @@
 obj-$(CONFIG_PMIC8058_MISC) += pmic8058-misc.o
 obj-$(CONFIG_PMIC8058_BATTALARM) += pmic8058-batt-alarm.o
 obj-$(CONFIG_TZCOM) += tzcom.o
+obj-$(CONFIG_QFP_FUSE) += qfp_fuse.o
diff --git a/drivers/misc/isa1200.c b/drivers/misc/isa1200.c
index a58c7d6..31c79a0 100644
--- a/drivers/misc/isa1200.c
+++ b/drivers/misc/isa1200.c
@@ -187,7 +187,7 @@
 	rc = isa1200_write_reg(client, ISA1200_HCTRL1, value);
 	if (rc < 0) {
 		pr_err("%s: i2c write failure\n", __func__);
-		return rc;
+		goto reset_gpios;
 	}
 
 	if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
@@ -224,6 +224,10 @@
 reset_hctrl1:
 	i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
 				ISA1200_HCTRL1_RESET);
+reset_gpios:
+	gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
+	if (haptic->is_len_gpio_valid == true)
+		gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
 	return rc;
 }
 
@@ -449,6 +453,11 @@
 	return 0;
 
 reset_hctrl0:
+	gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
+	if (haptic->is_len_gpio_valid == true)
+		gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
+	i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
+				ISA1200_HCTRL1_RESET);
 	i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
 					ISA1200_HCTRL0_RESET);
 setup_fail:
@@ -490,6 +499,10 @@
 
 	timed_output_dev_unregister(&haptic->dev);
 
+	gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
+	if (haptic->is_len_gpio_valid == true)
+		gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
+
 	gpio_free(haptic->pdata->hap_en_gpio);
 	if (haptic->is_len_gpio_valid == true)
 		gpio_free(haptic->pdata->hap_len_gpio);
diff --git a/drivers/misc/pm8xxx-vibrator.c b/drivers/misc/pm8xxx-vibrator.c
index 4f22efe..62e7b45 100644
--- a/drivers/misc/pm8xxx-vibrator.c
+++ b/drivers/misc/pm8xxx-vibrator.c
@@ -145,9 +145,8 @@
 					 timed_dev);
 	unsigned long flags;
 
-	spin_lock_irqsave(&vib->lock, flags);
-
 retry:
+	spin_lock_irqsave(&vib->lock, flags);
 	if (hrtimer_try_to_cancel(&vib->vib_timer) < 0) {
 		spin_unlock_irqrestore(&vib->lock, flags);
 		cpu_relax();
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 71d0fa6..918fc9e 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -831,7 +831,7 @@
 			 *
 			 * WARNING: eMMC rules are NOT the same as SD DDR
 			 */
-			if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
+			if (ddr == MMC_1_2V_DDR_MODE) {
 				err = mmc_set_signal_voltage(host,
 					MMC_SIGNAL_VOLTAGE_120, 0);
 				if (err)
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index fa91b53..b46bee6 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -76,6 +76,7 @@
 static int  msmsdcc_dbg_init(void);
 #endif
 
+static u64 dma_mask = DMA_BIT_MASK(32);
 static unsigned int msmsdcc_pwrsave = 1;
 
 static struct mmc_command dummy52cmd;
@@ -1529,7 +1530,7 @@
 			msmsdcc_do_cmdirq(host, status);
 		}
 
-		if (data) {
+		if (host->curr.data) {
 			/* Check for data errors */
 			if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|
 				      MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
@@ -3929,6 +3930,7 @@
 		if (ret)
 			goto sps_exit;
 	}
+	mmc_dev(mmc)->dma_mask = &dma_mask;
 
 	/*
 	 * Setup MMC host structure
diff --git a/drivers/net/msm_rmnet_bam.c b/drivers/net/msm_rmnet_bam.c
index bb20a3f..99a2c04 100644
--- a/drivers/net/msm_rmnet_bam.c
+++ b/drivers/net/msm_rmnet_bam.c
@@ -342,7 +342,12 @@
 	    ((struct net_device *)(dev))->name, p->stats.tx_packets,
 	    skb->len, skb->mark);
 	dev_kfree_skb_any(skb);
-	netif_wake_queue(dev);
+	if (netif_queue_stopped(dev) &&
+	    msm_bam_dmux_is_ch_low(p->ch_id)) {
+		DBG0("%s: Low WM hit, waking queue=%p\n",
+		      __func__, skb);
+		netif_wake_queue(dev);
+	}
 }
 
 static void bam_notify(void *dev, int event, unsigned long data)
@@ -452,7 +457,6 @@
 		return 0;
 	}
 
-	netif_stop_queue(dev);
 	if (!ul_is_connected) {
 		p->waiting_for_ul = 1;
 		msm_bam_dmux_kickoff_ul_wakeup();
@@ -460,6 +464,11 @@
 	}
 	_rmnet_xmit(skb, dev);
 
+	if (msm_bam_dmux_is_ch_full(p->ch_id)) {
+		netif_stop_queue(dev);
+		DBG0("%s: High WM hit, stopping queue=%p\n",    __func__, skb);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 1c56f34..7453068 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -14,8 +14,8 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
-#include <linux/firmware.h>
-#include <linux/parser.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
 #include <linux/wcnss_wlan.h>
 #include <linux/platform_data/qcom_wcnss_device.h>
 #include <linux/workqueue.h>
@@ -31,7 +31,7 @@
 /* module params */
 #define WCNSS_CONFIG_UNSPECIFIED (-1)
 static int has_48mhz_xo = WCNSS_CONFIG_UNSPECIFIED;
-module_param(has_48mhz_xo, int, S_IRUGO);
+module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(has_48mhz_xo, "Is an external 48 MHz XO present");
 
 static struct {
@@ -42,6 +42,7 @@
 	struct resource	*rx_irq_res;
 	struct resource	*gpios_5wire;
 	const struct dev_pm_ops *pm_ops;
+	int             triggered;
 	int             smd_channel_ready;
 	struct wcnss_wlan_config wlan_config;
 	struct delayed_work wcnss_work;
@@ -191,25 +192,16 @@
 	return 0;
 }
 
-static int __devinit
-wcnss_wlan_probe(struct platform_device *pdev)
+static int
+wcnss_trigger_config(struct platform_device *pdev)
 {
 	int ret;
 	struct qcom_wcnss_opts *pdata;
 
-	/* verify we haven't been called more than once */
-	if (penv) {
-		dev_err(&pdev->dev, "cannot handle multiple devices.\n");
-		return -ENODEV;
-	}
-
-	/* create an environment to track the device */
-	penv = kzalloc(sizeof(*penv), GFP_KERNEL);
-	if (!penv) {
-		dev_err(&pdev->dev, "cannot allocate device memory.\n");
-		return -ENOMEM;
-	}
-	penv->pdev = pdev;
+	/* make sure we are only triggered once */
+	if (penv->triggered)
+		return 0;
+	penv->triggered = 1;
 
 	/* initialize the WCNSS device configuration */
 	pdata = pdev->dev.platform_data;
@@ -281,6 +273,75 @@
 	return ret;
 }
 
+#ifndef MODULE
+static int wcnss_node_open(struct inode *inode, struct file *file)
+{
+	struct platform_device *pdev;
+
+	pr_info(DEVICE " triggered by userspace\n");
+
+	pdev = penv->pdev;
+	return wcnss_trigger_config(pdev);
+}
+
+static const struct file_operations wcnss_node_fops = {
+	.owner = THIS_MODULE,
+	.open = wcnss_node_open,
+};
+
+static struct miscdevice wcnss_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = DEVICE,
+	.fops = &wcnss_node_fops,
+};
+#endif /* ifndef MODULE */
+
+
+static int __devinit
+wcnss_wlan_probe(struct platform_device *pdev)
+{
+	/* verify we haven't been called more than once */
+	if (penv) {
+		dev_err(&pdev->dev, "cannot handle multiple devices.\n");
+		return -ENODEV;
+	}
+
+	/* create an environment to track the device */
+	penv = kzalloc(sizeof(*penv), GFP_KERNEL);
+	if (!penv) {
+		dev_err(&pdev->dev, "cannot allocate device memory.\n");
+		return -ENOMEM;
+	}
+	penv->pdev = pdev;
+
+#ifdef MODULE
+
+	/*
+	 * Since we were built as a module, we are running because
+	 * the module was loaded, therefore we assume userspace
+	 * applications are available to service PIL, so we can
+	 * trigger the WCNSS configuration now
+	 */
+	pr_info(DEVICE " probed in MODULE mode\n");
+	return wcnss_trigger_config(pdev);
+
+#else
+
+	/*
+	 * Since we were built into the kernel we'll be called as part
+	 * of kernel initialization.  We don't know if userspace
+	 * applications are available to service PIL at this time
+	 * (they probably are not), so we simply create a device node
+	 * here.  When userspace is available it should touch the
+	 * device so that we know that WCNSS configuration can take
+	 * place
+	 */
+	pr_info(DEVICE " probed in built-in mode\n");
+	return misc_register(&wcnss_misc);
+
+#endif
+}
+
 static int __devexit
 wcnss_wlan_remove(struct platform_device *pdev)
 {
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 75a6b5e..26441cd 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -13,7 +13,7 @@
 config SPS
 	bool "SPS support"
 	depends on (HAS_IOMEM && (ARCH_MSM8960 || ARCH_MSM8X60 \
-			|| ARCH_APQ8064 || ARCH_MSM9615))
+			|| ARCH_APQ8064 || ARCH_MSM9615 || ARCH_MSMCOPPER))
 	select GENERIC_ALLOCATOR
 	default n
 	help
@@ -28,10 +28,17 @@
 	depends on SPS
 	default n
 	help
-	The BAM-DMA is used for Memory-to-Memory transfers.
-	The main use cases is RPC between processors.
-	The BAM-DMA hardware has 2 registers sets:
-	1. A BAM HW like all the peripherals.
-	2. A DMA channel configuration (i.e. channel priority).
+	  The BAM-DMA is used for Memory-to-Memory transfers.
+	  The main use cases is RPC between processors.
+	  The BAM-DMA hardware has 2 registers sets:
+		1. A BAM HW like all the peripherals.
+		2. A DMA channel configuration (i.e. channel priority).
+
+config SPS_SUPPORT_NDP_BAM
+	bool "SPS support NDP BAM"
+	depends on SPS
+	default n
+	help
+	  No-Data-Path BAM is used to improve BAM performance.
 
 endmenu
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index 2af4fa4..4279603 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -28,6 +28,286 @@
 #define BAM_MIN_VERSION 2
 #define BAM_MAX_VERSION 0x1f
 
+#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
+
+/* Maximum number of execution environment */
+#define BAM_MAX_EES 8
+
+/**
+ *  BAM Hardware registers.
+ *
+ */
+#define CTRL                        (0x0)
+#define REVISION                    (0x4)
+#define SW_REVISION                 (0x80)
+#define NUM_PIPES                   (0x3c)
+#define TIMER                       (0x40)
+#define TIMER_CTRL                  (0x44)
+#define DESC_CNT_TRSHLD             (0x8)
+#define IRQ_SRCS                    (0xc)
+#define IRQ_SRCS_MSK                (0x10)
+#define IRQ_SRCS_UNMASKED           (0x30)
+#define IRQ_STTS                    (0x14)
+#define IRQ_CLR                     (0x18)
+#define IRQ_EN                      (0x1c)
+#define AHB_MASTER_ERR_CTRLS        (0x24)
+#define AHB_MASTER_ERR_ADDR         (0x28)
+#define AHB_MASTER_ERR_DATA         (0x2c)
+#define TRUST_REG                   (0x70)
+#define TEST_BUS_SEL                (0x74)
+#define TEST_BUS_REG                (0x78)
+#define CNFG_BITS                   (0x7c)
+#define IRQ_SRCS_EE(n)             (0x800 + 128 * (n))
+#define IRQ_SRCS_MSK_EE(n)         (0x804 + 128 * (n))
+#define IRQ_SRCS_UNMASKED_EE(n)    (0x808 + 128 * (n))
+
+#define P_CTRL(n)                  (0x1000 + 4096 * (n))
+#define P_RST(n)                   (0x1004 + 4096 * (n))
+#define P_HALT(n)                  (0x1008 + 4096 * (n))
+#define P_IRQ_STTS(n)              (0x1010 + 4096 * (n))
+#define P_IRQ_CLR(n)               (0x1014 + 4096 * (n))
+#define P_IRQ_EN(n)                (0x1018 + 4096 * (n))
+#define P_TIMER(n)                 (0x101c + 4096 * (n))
+#define P_TIMER_CTRL(n)            (0x1020 + 4096 * (n))
+#define P_PRDCR_SDBND(n)           (0x1024 + 4096 * (n))
+#define P_CNSMR_SDBND(n)           (0x1028 + 4096 * (n))
+#define P_TRUST_REG(n)             (0x1030 + 4096 * (n))
+#define P_EVNT_DEST_ADDR(n)        (0x182c + 4096 * (n))
+#define P_EVNT_REG(n)              (0x1818 + 4096 * (n))
+#define P_SW_OFSTS(n)              (0x1800 + 4096 * (n))
+#define P_DATA_FIFO_ADDR(n)        (0x1824 + 4096 * (n))
+#define P_DESC_FIFO_ADDR(n)        (0x181c + 4096 * (n))
+#define P_EVNT_GEN_TRSHLD(n)       (0x1828 + 4096 * (n))
+#define P_FIFO_SIZES(n)            (0x1820 + 4096 * (n))
+#define P_RETR_CNTXT(n)            (0x1834 + 4096 * (n))
+#define P_SI_CNTXT(n)              (0x1838 + 4096 * (n))
+#define P_DF_CNTXT(n)              (0x1830 + 4096 * (n))
+#define P_AU_PSM_CNTXT_1(n)        (0x1804 + 4096 * (n))
+#define P_PSM_CNTXT_2(n)           (0x1808 + 4096 * (n))
+#define P_PSM_CNTXT_3(n)           (0x180c + 4096 * (n))
+#define P_PSM_CNTXT_4(n)           (0x1810 + 4096 * (n))
+#define P_PSM_CNTXT_5(n)           (0x1814 + 4096 * (n))
+
+/**
+ *  BAM Hardware registers bitmask.
+ *  format: <register>_<field>
+ *
+ */
+/* CTRL */
+#define IBC_DISABLE                            0x10000
+#define BAM_CACHED_DESC_STORE                   0x8000
+#define BAM_DESC_CACHE_SEL                      0x6000
+#define BAM_EN_ACCUM                              0x10
+#define BAM_EN                                     0x2
+#define BAM_SW_RST                                 0x1
+
+/* REVISION */
+#define BAM_INACTIV_TMR_BASE                0xff000000
+#define BAM_CMD_DESC_EN                       0x800000
+#define BAM_DESC_CACHE_DEPTH                  0x600000
+#define BAM_NUM_INACTIV_TMRS                  0x100000
+#define BAM_INACTIV_TMRS_EXST                  0x80000
+#define BAM_HIGH_FREQUENCY_BAM                 0x40000
+#define BAM_HAS_NO_BYPASS                      0x20000
+#define BAM_SECURED                            0x10000
+#define BAM_USE_VMIDMT                          0x8000
+#define BAM_AXI_ACTIVE                          0x4000
+#define BAM_CE_BUFFER_SIZE                      0x2000
+#define BAM_NUM_EES                              0xf00
+#define BAM_REVISION                              0xff
+
+/* SW_REVISION */
+#define BAM_MAJOR                           0xf0000000
+#define BAM_MINOR                            0xfff0000
+#define BAM_STEP                                0xffff
+
+/* NUM_PIPES */
+#define BAM_NON_PIPE_GRP                    0xff000000
+#define BAM_PERIPH_NON_PIPE_GRP               0xff0000
+#define BAM_NUM_PIPES                             0xff
+
+/* TIMER */
+#define BAM_TIMER                               0xffff
+
+/* TIMER_CTRL */
+#define TIMER_RST                           0x80000000
+#define TIMER_RUN                           0x40000000
+#define TIMER_MODE                          0x20000000
+#define TIMER_TRSHLD                            0xffff
+
+/* DESC_CNT_TRSHLD */
+#define BAM_DESC_CNT_TRSHLD                     0xffff
+
+/* IRQ_SRCS */
+#define BAM_IRQ                         0x80000000
+#define P_IRQ                           0x7fffffff
+
+/* IRQ_STTS */
+#define IRQ_STTS_BAM_TIMER_IRQ                         0x10
+#define IRQ_STTS_BAM_EMPTY_IRQ                          0x8
+#define IRQ_STTS_BAM_ERROR_IRQ                          0x4
+#define IRQ_STTS_BAM_HRESP_ERR_IRQ                      0x2
+
+/* IRQ_CLR */
+#define IRQ_CLR_BAM_TIMER_IRQ                          0x10
+#define IRQ_CLR_BAM_EMPTY_CLR                           0x8
+#define IRQ_CLR_BAM_ERROR_CLR                           0x4
+#define IRQ_CLR_BAM_HRESP_ERR_CLR                       0x2
+
+/* IRQ_EN */
+#define IRQ_EN_BAM_TIMER_IRQ                           0x10
+#define IRQ_EN_BAM_EMPTY_EN                             0x8
+#define IRQ_EN_BAM_ERROR_EN                             0x4
+#define IRQ_EN_BAM_HRESP_ERR_EN                         0x2
+
+/* AHB_MASTER_ERR_CTRLS */
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HVMID         0x7c0000
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_DIRECT_MODE    0x20000
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HCID           0x1f000
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HPROT            0xf00
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HBURST            0xe0
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HSIZE             0x18
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HWRITE             0x4
+#define AHB_MASTER_ERR_CTRLS_BAM_ERR_HTRANS             0x3
+
+/* TRUST_REG  */
+#define BAM_VMID                                0x1f00
+#define BAM_RST_BLOCK                             0x80
+#define BAM_EE                                     0x7
+
+/* TEST_BUS_SEL */
+#define BAM_DATA_ERASE                         0x40000
+#define BAM_DATA_FLUSH                         0x20000
+#define BAM_CLK_ALWAYS_ON                      0x10000
+#define BAM_TESTBUS_SEL                           0x7f
+
+/* CNFG_BITS */
+#define CNFG_BITS_BAM_CD_ENABLE                   0x8000000
+#define CNFG_BITS_BAM_AU_ACCUMED                  0x4000000
+#define CNFG_BITS_BAM_PSM_P_HD_DATA               0x2000000
+#define CNFG_BITS_BAM_REG_P_EN                    0x1000000
+#define CNFG_BITS_BAM_WB_DSC_AVL_P_RST             0x800000
+#define CNFG_BITS_BAM_WB_RETR_SVPNT                0x400000
+#define CNFG_BITS_BAM_WB_CSW_ACK_IDL               0x200000
+#define CNFG_BITS_BAM_WB_BLK_CSW                   0x100000
+#define CNFG_BITS_BAM_WB_P_RES                      0x80000
+#define CNFG_BITS_BAM_SI_P_RES                      0x40000
+#define CNFG_BITS_BAM_AU_P_RES                      0x20000
+#define CNFG_BITS_BAM_PSM_P_RES                     0x10000
+#define CNFG_BITS_BAM_PSM_CSW_REQ                    0x8000
+#define CNFG_BITS_BAM_SB_CLK_REQ                     0x4000
+#define CNFG_BITS_BAM_IBC_DISABLE                    0x2000
+#define CNFG_BITS_BAM_NO_EXT_P_RST                   0x1000
+#define CNFG_BITS_BAM_FULL_PIPE                       0x800
+#define CNFG_BITS_BAM_PIPE_CNFG                         0x4
+
+/* P_ctrln */
+#define P_LOCK_GROUP                          0x1f0000
+#define P_WRITE_NWD                              0x800
+#define P_PREFETCH_LIMIT                         0x600
+#define P_AUTO_EOB_SEL                           0x180
+#define P_AUTO_EOB                                0x40
+#define P_SYS_MODE                                0x20
+#define P_SYS_STRM                                0x10
+#define P_DIRECTION                                0x8
+#define P_EN                                       0x2
+
+/* P_RSTn */
+#define P_RST_P_SW_RST                             0x1
+
+/* P_HALTn */
+#define P_HALT_P_PROD_HALTED                       0x2
+#define P_HALT_P_HALT                              0x1
+
+/* P_TRUST_REGn */
+#define BAM_P_VMID                              0x1f00
+#define BAM_P_EE                                   0x7
+
+/* P_IRQ_STTSn */
+#define P_IRQ_STTS_P_TRNSFR_END_IRQ               0x20
+#define P_IRQ_STTS_P_ERR_IRQ                      0x10
+#define P_IRQ_STTS_P_OUT_OF_DESC_IRQ               0x8
+#define P_IRQ_STTS_P_WAKE_IRQ                      0x4
+#define P_IRQ_STTS_P_TIMER_IRQ                     0x2
+#define P_IRQ_STTS_P_PRCSD_DESC_IRQ                0x1
+
+/* P_IRQ_CLRn */
+#define P_IRQ_CLR_P_TRNSFR_END_CLR                0x20
+#define P_IRQ_CLR_P_ERR_CLR                       0x10
+#define P_IRQ_CLR_P_OUT_OF_DESC_CLR                0x8
+#define P_IRQ_CLR_P_WAKE_CLR                       0x4
+#define P_IRQ_CLR_P_TIMER_CLR                      0x2
+#define P_IRQ_CLR_P_PRCSD_DESC_CLR                 0x1
+
+/* P_IRQ_ENn */
+#define P_IRQ_EN_P_TRNSFR_END_EN                  0x20
+#define P_IRQ_EN_P_ERR_EN                         0x10
+#define P_IRQ_EN_P_OUT_OF_DESC_EN                  0x8
+#define P_IRQ_EN_P_WAKE_EN                         0x4
+#define P_IRQ_EN_P_TIMER_EN                        0x2
+#define P_IRQ_EN_P_PRCSD_DESC_EN                   0x1
+
+/* P_TIMERn */
+#define P_TIMER_P_TIMER                         0xffff
+
+/* P_TIMER_ctrln */
+#define P_TIMER_RST                         0x80000000
+#define P_TIMER_RUN                         0x40000000
+#define P_TIMER_MODE                        0x20000000
+#define P_TIMER_TRSHLD                          0xffff
+
+/* P_PRDCR_SDBNDn */
+#define P_PRDCR_SDBNDn_BAM_P_SB_UPDATED      0x1000000
+#define P_PRDCR_SDBNDn_BAM_P_TOGGLE           0x100000
+#define P_PRDCR_SDBNDn_BAM_P_CTRL              0xf0000
+#define P_PRDCR_SDBNDn_BAM_P_BYTES_FREE         0xffff
+
+/* P_CNSMR_SDBNDn */
+#define P_CNSMR_SDBNDn_BAM_P_SB_UPDATED      0x1000000
+#define P_CNSMR_SDBNDn_BAM_P_WAIT_4_ACK       0x800000
+#define P_CNSMR_SDBNDn_BAM_P_ACK_TOGGLE       0x400000
+#define P_CNSMR_SDBNDn_BAM_P_ACK_TOGGLE_R     0x200000
+#define P_CNSMR_SDBNDn_BAM_P_TOGGLE           0x100000
+#define P_CNSMR_SDBNDn_BAM_P_CTRL              0xf0000
+#define P_CNSMR_SDBNDn_BAM_P_BYTES_AVAIL        0xffff
+
+/* P_EVNT_regn */
+#define P_BYTES_CONSUMED                    0xffff0000
+#define P_DESC_FIFO_PEER_OFST                   0xffff
+
+/* P_SW_ofstsn */
+#define SW_OFST_IN_DESC                     0xffff0000
+#define SW_DESC_OFST                            0xffff
+
+/* P_EVNT_GEN_TRSHLDn */
+#define P_EVNT_GEN_TRSHLD_P_TRSHLD              0xffff
+
+/* P_FIFO_sizesn */
+#define P_DATA_FIFO_SIZE                    0xffff0000
+#define P_DESC_FIFO_SIZE                        0xffff
+
+#define P_RETR_CNTXT_RETR_DESC_OFST            0xffff0000
+#define P_RETR_CNTXT_RETR_OFST_IN_DESC             0xffff
+#define P_SI_CNTXT_SI_DESC_OFST                    0xffff
+#define P_DF_CNTXT_WB_ACCUMULATED              0xffff0000
+#define P_DF_CNTXT_DF_DESC_OFST                    0xffff
+#define P_AU_PSM_CNTXT_1_AU_PSM_ACCUMED        0xffff0000
+#define P_AU_PSM_CNTXT_1_AU_ACKED                  0xffff
+#define P_PSM_CNTXT_2_PSM_DESC_VALID           0x80000000
+#define P_PSM_CNTXT_2_PSM_DESC_IRQ             0x40000000
+#define P_PSM_CNTXT_2_PSM_DESC_IRQ_DONE        0x20000000
+#define P_PSM_CNTXT_2_PSM_GENERAL_BITS         0x1e000000
+#define P_PSM_CNTXT_2_PSM_CONS_STATE            0x1c00000
+#define P_PSM_CNTXT_2_PSM_PROD_SYS_STATE         0x380000
+#define P_PSM_CNTXT_2_PSM_PROD_B2B_STATE          0x70000
+#define P_PSM_CNTXT_2_PSM_DESC_SIZE                0xffff
+#define P_PSM_CNTXT_4_PSM_DESC_OFST            0xffff0000
+#define P_PSM_CNTXT_4_PSM_SAVED_ACCUMED_SIZE       0xffff
+#define P_PSM_CNTXT_5_PSM_BLOCK_BYTE_CNT       0xffff0000
+#define P_PSM_CNTXT_5_PSM_OFST_IN_DESC             0xffff
+
+#else
+
 /* Maximum number of execution environment */
 #define BAM_MAX_EES 4
 
@@ -263,6 +543,7 @@
 #define P_PSM_CNTXT_4_PSM_SAVED_ACCUMED_SIZE       0xffff
 #define P_PSM_CNTXT_5_PSM_BLOCK_BYTE_CNT       0xffff0000
 #define P_PSM_CNTXT_5_PSM_OFST_IN_DESC             0xffff
+#endif
 
 #define BAM_ERROR   (-1)
 
@@ -658,9 +939,10 @@
 void bam_pipe_satellite_mti(void *base, u32 pipe, u32 irq_gen_addr, u32 ee)
 {
 	bam_write_reg(base, P_IRQ_EN(pipe), 0);
+#ifndef CONFIG_SPS_SUPPORT_NDP_BAM
 	bam_write_reg(base, P_IRQ_DEST_ADDR(pipe), irq_gen_addr);
-
 	bam_write_reg_field(base, IRQ_SIC_SEL, (1 << pipe), 1);
+#endif
 	bam_write_reg_field(base, IRQ_SRCS_MSK, (1 << pipe), 1);
 }
 
@@ -680,9 +962,9 @@
 	 * interrupt. Since the remote processor enable both SIC and interrupt,
 	 * the interrupt enable mask must be set to zero for polling mode.
 	 */
-
+#ifndef CONFIG_SPS_SUPPORT_NDP_BAM
 	bam_write_reg(base, P_IRQ_DEST_ADDR(pipe), irq_gen_addr);
-
+#endif
 	if (!irq_en)
 		src_mask = 0;
 
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index e43166e..b002657 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>	/* platform_get_resource_byname() */
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
+#include <linux/of.h>
 #include <mach/msm_sps.h>	/* msm_sps_platform_data */
 
 #include "sps_bam.h"
@@ -1428,13 +1429,74 @@
 	return 0;
 }
 
+/**
+ * Read data from device tree
+ */
+static int get_device_tree_data(struct platform_device *pdev)
+{
+#ifdef CONFIG_SPS_SUPPORT_BAMDMA
+	struct resource *resource;
+
+	if (of_property_read_u32((&pdev->dev)->of_node,
+				"qcom,bam-dma-res-pipes",
+				&sps->bamdma_restricted_pipes))
+		return -EINVAL;
+	else
+		SPS_DBG("sps:bamdma_restricted_pipes=0x%x.",
+			sps->bamdma_restricted_pipes);
+
+	resource  = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (resource) {
+		sps->bamdma_bam_phys_base = resource->start;
+		sps->bamdma_bam_size = resource_size(resource);
+		SPS_DBG("sps:bamdma_bam.base=0x%x,size=0x%x.",
+			sps->bamdma_bam_phys_base,
+			sps->bamdma_bam_size);
+	} else {
+		SPS_ERR("sps:BAM DMA BAM mem unavailable.");
+		return -ENODEV;
+	}
+
+	resource  = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (resource) {
+		sps->bamdma_dma_phys_base = resource->start;
+		sps->bamdma_dma_size = resource_size(resource);
+		SPS_DBG("sps:bamdma_dma.base=0x%x,size=0x%x.",
+			sps->bamdma_dma_phys_base,
+			sps->bamdma_dma_size);
+	} else {
+		SPS_ERR("sps:BAM DMA mem unavailable.");
+		return -ENODEV;
+	}
+
+	resource  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (resource) {
+		sps->bamdma_irq = resource->start;
+		SPS_DBG("sps:bamdma_irq=%d.", sps->bamdma_irq);
+	} else {
+		SPS_ERR("sps:BAM DMA IRQ unavailable.");
+		return -ENODEV;
+	}
+#endif
+
+	return 0;
+}
+
 static int __devinit msm_sps_probe(struct platform_device *pdev)
 {
 	int ret;
 
 	SPS_DBG("sps:msm_sps_probe.");
 
-	ret = get_platform_data(pdev);
+	if (pdev->dev.of_node) {
+		SPS_DBG("sps:get data from device tree.");
+		ret = get_device_tree_data(pdev);
+
+	} else {
+		SPS_DBG("sps:get platform data.");
+		ret = get_platform_data(pdev);
+	}
+
 	if (ret)
 		return -ENODEV;
 
@@ -1542,11 +1604,18 @@
 	return 0;
 }
 
+static struct of_device_id msm_sps_match[] = {
+	{	.compatible = "qcom,msm_sps",
+	},
+	{}
+};
+
 static struct platform_driver msm_sps_driver = {
 	.probe          = msm_sps_probe,
 	.driver		= {
 		.name	= SPS_DRV_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = msm_sps_match,
 	},
 	.remove		= __exit_p(msm_sps_remove),
 };
diff --git a/drivers/platform/msm/sps/sps_dma.c b/drivers/platform/msm/sps/sps_dma.c
index 9f42403..b650098 100644
--- a/drivers/platform/msm/sps/sps_dma.c
+++ b/drivers/platform/msm/sps/sps_dma.c
@@ -26,14 +26,24 @@
  */
 
 #define DMA_ENBL			(0x00000000)
+#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
+#define DMA_REVISION			(0x00000004)
+#define DMA_CONFIG			(0x00000008)
+#define DMA_CHNL_CONFIG(n)		(0x00001000 + 4096 * (n))
+#else
 #define DMA_CHNL_CONFIG(n)		(0x00000004 + 4 * (n))
 #define DMA_CONFIG			(0x00000040)
+#endif
 
 /**
  * masks
  */
 
 /* DMA_CHNL_confign */
+#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
+#define DMA_CHNL_PRODUCER_PIPE_ENABLED	0x40000
+#define DMA_CHNL_CONSUMER_PIPE_ENABLED	0x20000
+#endif
 #define DMA_CHNL_HALT_DONE		0x10000
 #define DMA_CHNL_HALT			0x1000
 #define DMA_CHNL_ENABLE                 0x100
diff --git a/drivers/platform/msm/sps/sps_mem.c b/drivers/platform/msm/sps/sps_mem.c
index 3aee4ba..31c1314 100644
--- a/drivers/platform/msm/sps/sps_mem.c
+++ b/drivers/platform/msm/sps/sps_mem.c
@@ -104,10 +104,13 @@
  */
 int sps_mem_init(u32 pipemem_phys_base, u32 pipemem_size)
 {
+#ifndef CONFIG_SPS_SUPPORT_NDP_BAM
 	int res;
+#endif
 	/* 2^8=128. The desc-fifo and data-fifo minimal allocation. */
 	int min_alloc_order = 8;
 
+#ifndef CONFIG_SPS_SUPPORT_NDP_BAM
 	iomem_phys = pipemem_phys_base;
 	iomem_size = pipemem_size;
 
@@ -125,11 +128,14 @@
 	iomem_offset = 0;
 	SPS_DBG("sps:sps_mem_init.iomem_phys=0x%x,iomem_virt=0x%x.",
 		iomem_phys, (u32) iomem_virt);
+#endif
 
 	pool = gen_pool_create(min_alloc_order, nid);
+#ifndef CONFIG_SPS_SUPPORT_NDP_BAM
 	res = gen_pool_add(pool, (u32) iomem_virt, iomem_size, nid);
 	if (res)
 		return res;
+#endif
 
 	return 0;
 }
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 7c8dfea..3dfa68e 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -338,6 +338,13 @@
 	help
 	  Say Y here to enable support for pm8921 chip bms subdevice
 
+config LTC4088_CHARGER
+	tristate "LTC4088 Charger driver"
+	depends on GPIOLIB
+	help
+	  Say Y here to enable support for ltc4088 chip charger. It controls the
+	  operations through GPIO pins.
+
 config PM8921_BMS
 	select PM8XXX_CCADC
 	tristate "PM8921 Battery Monitoring System driver"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index e168590..03db839 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -48,3 +48,4 @@
 obj-$(CONFIG_PM8XXX_CCADC)	+= pm8xxx-ccadc.o
 obj-$(CONFIG_PM8921_BMS)	+= pm8921-bms.o
 obj-$(CONFIG_PM8921_CHARGER)	+= pm8921-charger.o
+obj-$(CONFIG_LTC4088_CHARGER)	+= ltc4088-charger.o
diff --git a/drivers/power/ltc4088-charger.c b/drivers/power/ltc4088-charger.c
new file mode 100644
index 0000000..dbc75cd
--- /dev/null
+++ b/drivers/power/ltc4088-charger.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+#define pr_fmt(fmt)	"%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/power/ltc4088-charger.h>
+
+#define MAX_CURRENT_UA(n)	(n)
+#define MAX_CURRENT_MA(n)	(n * MAX_CURRENT_UA(1000))
+
+/**
+ * ltc4088_max_current - A typical current values supported by the charger
+ * @LTC4088_MAX_CURRENT_100mA:  100mA current
+ * @LTC4088_MAX_CURRENT_500mA:  500mA current
+ * @LTC4088_MAX_CURRENT_1A:     1A current
+ */
+enum ltc4088_max_current {
+	LTC4088_MAX_CURRENT_100mA = 100,
+	LTC4088_MAX_CURRENT_500mA = 500,
+	LTC4088_MAX_CURRENT_1A = 1000,
+};
+
+/**
+ * struct ltc4088_chg_chip - Device information
+ * @dev:			Device pointer to access the parent
+ * @lock:			Enable mutual exclusion
+ * @usb_psy:			USB device information
+ * @gpio_mode_select_d0:	GPIO #pin for D0 charger line
+ * @gpio_mode_select_d1:	GPIO #pin for D1 charger line
+ * @gpio_mode_select_d2:	GPIO #pin for D2 charger line
+ * @max_current:		Maximum current that is supplied at this time
+ */
+struct ltc4088_chg_chip {
+	struct device		*dev;
+	struct mutex		lock;
+	struct power_supply	usb_psy;
+	unsigned int		gpio_mode_select_d0;
+	unsigned int		gpio_mode_select_d1;
+	unsigned int		gpio_mode_select_d2;
+	unsigned int		max_current;
+};
+
+static enum power_supply_property pm_power_props[] = {
+	POWER_SUPPLY_PROP_CURRENT_MAX,
+	POWER_SUPPLY_PROP_ONLINE,
+};
+
+static char *pm_power_supplied_to[] = {
+	"battery",
+};
+
+static int ltc4088_set_charging(struct ltc4088_chg_chip *chip, bool enable)
+{
+	mutex_lock(&chip->lock);
+
+	if (enable) {
+		gpio_set_value_cansleep(chip->gpio_mode_select_d2, 0);
+	} else {
+		/* When disabling charger, set the max current to 0 also */
+		chip->max_current = 0;
+		gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d2, 1);
+	}
+
+	mutex_unlock(&chip->lock);
+
+	return 0;
+}
+
+static void ltc4088_set_max_current(struct ltc4088_chg_chip *chip, int value)
+{
+	mutex_lock(&chip->lock);
+
+	/* If current is less than 100mA, we can not support that granularity */
+	if (value <  MAX_CURRENT_MA(LTC4088_MAX_CURRENT_100mA)) {
+		chip->max_current = 0;
+		gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+	} else if (value <  MAX_CURRENT_MA(LTC4088_MAX_CURRENT_500mA)) {
+		chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_100mA);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d0, 0);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d1, 0);
+	} else if (value <  MAX_CURRENT_MA(LTC4088_MAX_CURRENT_1A)) {
+		chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_500mA);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d0, 0);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+	} else {
+		chip->max_current = MAX_CURRENT_MA(LTC4088_MAX_CURRENT_1A);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+		gpio_set_value_cansleep(chip->gpio_mode_select_d1, 0);
+	}
+
+	mutex_unlock(&chip->lock);
+}
+
+static void ltc4088_set_charging_off(struct ltc4088_chg_chip *chip)
+{
+	gpio_set_value_cansleep(chip->gpio_mode_select_d0, 1);
+	gpio_set_value_cansleep(chip->gpio_mode_select_d1, 1);
+}
+
+static int ltc4088_set_initial_state(struct ltc4088_chg_chip *chip)
+{
+	int rc;
+
+	rc = gpio_request(chip->gpio_mode_select_d0, "ltc4088_D0");
+	if (rc) {
+		pr_err("gpio request failed for GPIO %d\n",
+				chip->gpio_mode_select_d0);
+		return rc;
+	}
+
+	rc = gpio_request(chip->gpio_mode_select_d1, "ltc4088_D1");
+	if (rc) {
+		pr_err("gpio request failed for GPIO %d\n",
+				chip->gpio_mode_select_d1);
+		goto gpio_err_d0;
+	}
+
+	rc = gpio_request(chip->gpio_mode_select_d2, "ltc4088_D2");
+	if (rc) {
+		pr_err("gpio request failed for GPIO %d\n",
+				chip->gpio_mode_select_d2);
+		goto gpio_err_d1;
+	}
+
+	rc = gpio_direction_output(chip->gpio_mode_select_d0, 0);
+	if (rc) {
+		pr_err("failed to set direction for GPIO %d\n",
+				chip->gpio_mode_select_d0);
+		goto gpio_err_d2;
+	}
+
+	rc = gpio_direction_output(chip->gpio_mode_select_d1, 0);
+	if (rc) {
+		pr_err("failed to set direction for GPIO %d\n",
+				chip->gpio_mode_select_d1);
+		goto gpio_err_d2;
+	}
+
+	rc = gpio_direction_output(chip->gpio_mode_select_d2, 1);
+	if (rc) {
+		pr_err("failed to set direction for GPIO %d\n",
+				chip->gpio_mode_select_d2);
+		goto gpio_err_d2;
+	}
+
+	return 0;
+
+gpio_err_d2:
+	gpio_free(chip->gpio_mode_select_d2);
+gpio_err_d1:
+	gpio_free(chip->gpio_mode_select_d1);
+gpio_err_d0:
+	gpio_free(chip->gpio_mode_select_d0);
+	return rc;
+}
+
+static int pm_power_get_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  union power_supply_propval *val)
+{
+	struct ltc4088_chg_chip *chip;
+
+	if (psy->type == POWER_SUPPLY_TYPE_USB) {
+		chip = container_of(psy, struct ltc4088_chg_chip,
+						usb_psy);
+		switch (psp) {
+		case POWER_SUPPLY_PROP_ONLINE:
+			if (chip->max_current)
+				val->intval = 1;
+			else
+				val->intval = 0;
+			break;
+		case POWER_SUPPLY_PROP_CURRENT_MAX:
+			val->intval = chip->max_current;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int pm_power_set_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  const union power_supply_propval *val)
+{
+	struct ltc4088_chg_chip *chip;
+
+	if (psy->type == POWER_SUPPLY_TYPE_USB) {
+		chip = container_of(psy, struct ltc4088_chg_chip,
+						usb_psy);
+		switch (psp) {
+		case POWER_SUPPLY_PROP_ONLINE:
+			ltc4088_set_charging(chip, val->intval);
+			break;
+		case POWER_SUPPLY_PROP_CURRENT_MAX:
+			ltc4088_set_max_current(chip, val->intval);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int __devinit ltc4088_charger_probe(struct platform_device *pdev)
+{
+	int rc;
+	struct ltc4088_chg_chip *chip;
+	const struct ltc4088_charger_platform_data *pdata
+			= pdev->dev.platform_data;
+
+	if (!pdata) {
+		pr_err("missing platform data\n");
+		return -EINVAL;
+	}
+
+	chip = kzalloc(sizeof(struct ltc4088_chg_chip),
+					GFP_KERNEL);
+	if (!chip) {
+		pr_err("Cannot allocate pm_chg_chip\n");
+		return -ENOMEM;
+	}
+
+	chip->dev = &pdev->dev;
+
+	if (pdata->gpio_mode_select_d0 < 0 ||
+		 pdata->gpio_mode_select_d1 < 0 ||
+		 pdata->gpio_mode_select_d2 < 0) {
+		pr_err("Invalid platform data supplied\n");
+		rc = -EINVAL;
+		goto free_chip;
+	}
+
+	mutex_init(&chip->lock);
+
+	chip->gpio_mode_select_d0 = pdata->gpio_mode_select_d0;
+	chip->gpio_mode_select_d1 = pdata->gpio_mode_select_d1;
+	chip->gpio_mode_select_d2 = pdata->gpio_mode_select_d2;
+
+	chip->usb_psy.name = "usb",
+	chip->usb_psy.type = POWER_SUPPLY_TYPE_USB,
+	chip->usb_psy.supplied_to = pm_power_supplied_to,
+	chip->usb_psy.num_supplicants = ARRAY_SIZE(pm_power_supplied_to),
+	chip->usb_psy.properties = pm_power_props,
+	chip->usb_psy.num_properties = ARRAY_SIZE(pm_power_props),
+	chip->usb_psy.get_property = pm_power_get_property,
+	chip->usb_psy.set_property = pm_power_set_property,
+
+	rc = power_supply_register(chip->dev, &chip->usb_psy);
+	if (rc < 0) {
+		pr_err("power_supply_register usb failed rc = %d\n", rc);
+		goto free_chip;
+	}
+
+	platform_set_drvdata(pdev, chip);
+
+	rc = ltc4088_set_initial_state(chip);
+	if (rc < 0) {
+		pr_err("setting initial state failed rc = %d\n", rc);
+		goto unregister_usb;
+	}
+
+	return 0;
+
+unregister_usb:
+	platform_set_drvdata(pdev, NULL);
+	power_supply_unregister(&chip->usb_psy);
+free_chip:
+	kfree(chip);
+
+	return rc;
+}
+
+static int __devexit ltc4088_charger_remove(struct platform_device *pdev)
+{
+	struct ltc4088_chg_chip *chip = platform_get_drvdata(pdev);
+
+	ltc4088_set_charging_off(chip);
+
+	gpio_free(chip->gpio_mode_select_d2);
+	gpio_free(chip->gpio_mode_select_d1);
+	gpio_free(chip->gpio_mode_select_d0);
+
+	power_supply_unregister(&chip->usb_psy);
+
+	platform_set_drvdata(pdev, NULL);
+	mutex_destroy(&chip->lock);
+	kfree(chip);
+
+	return 0;
+}
+
+static struct platform_driver ltc4088_charger_driver = {
+	.probe	= ltc4088_charger_probe,
+	.remove	= __devexit_p(ltc4088_charger_remove),
+	.driver	= {
+		.name	= LTC4088_CHARGER_DEV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ltc4088_charger_init(void)
+{
+	return platform_driver_register(&ltc4088_charger_driver);
+}
+
+static void __exit ltc4088_charger_exit(void)
+{
+	platform_driver_unregister(&ltc4088_charger_driver);
+}
+
+subsys_initcall(ltc4088_charger_init);
+module_exit(ltc4088_charger_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("LTC4088 charger/battery driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" LTC4088_CHARGER_DEV_NAME);
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 6741ef4..f4c86d4 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -120,6 +120,15 @@
 module_param_cb(last_ocv_uv, &bms_param_ops, &last_ocv_uv, 0644);
 module_param_cb(last_soc, &bms_param_ops, &last_soc, 0644);
 
+/*
+ * bms_fake_battery is write only, this value is set in setups where a
+ * battery emulator is used instead of a real battery. This makes the
+ * bms driver report a higher value of charge regardless of the calculated
+ * state of charge.
+ */
+static int bms_fake_battery;
+module_param(bms_fake_battery, int, 0644);
+
 static int interpolate_fcc(struct pm8921_bms_chip *chip, int batt_temp);
 static void readjust_fcc_table(void)
 {
@@ -1015,8 +1024,6 @@
  *				- unusable charge (due to battery resistance)
  * SOC% = (remaining usable charge/ fcc - usable_charge);
  */
-#define BMS_BATT_NOMINAL	3700000
-#define MIN_OPERABLE_SOC	10
 #define BATTERY_POWER_SUPPLY_SOC	53
 static int calculate_state_of_charge(struct pm8921_bms_chip *chip,
 						int batt_temp, int chargecycles)
@@ -1040,22 +1047,10 @@
 		soc = 100;
 	pr_debug("SOC = %u%%\n", soc);
 
-	if (soc < MIN_OPERABLE_SOC) {
-		int ocv = 0, rc;
-
-		rc = adc_based_ocv(chip, &ocv);
-		if (rc == 0 && ocv >= BMS_BATT_NOMINAL) {
-			/*
-			 * The ocv doesnt seem to have dropped for
-			 * soc to go negative.
-			 * The setup must be using a power supply
-			 * instead of real batteries.
-			 * Fake high enough soc to prevent userspace
-			 * shutdown for low battery
-			 */
-			soc = BATTERY_POWER_SUPPLY_SOC;
-			pr_debug("Adjusting SOC to %d\n", soc);
-		}
+	if (bms_fake_battery) {
+		soc = BATTERY_POWER_SUPPLY_SOC;
+		pr_debug("setting SOC = %u%% bms_fake_battery = %d\n", soc,
+							bms_fake_battery);
 	}
 
 	if (soc < 0) {
@@ -1069,6 +1064,7 @@
 				last_ocv_uv, chargecycles, batt_temp,
 				fcc, soc);
 		update_userspace = 0;
+		soc = 0;
 	}
 
 	if (last_soc == -EINVAL || soc <= last_soc) {
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index a91630a..6b05643 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -250,7 +250,7 @@
 	int				trkl_current;
 	int				weak_current;
 	int				vin_min;
-	int				*thermal_mitigation;
+	unsigned int			*thermal_mitigation;
 	int				thermal_levels;
 	struct delayed_work		update_heartbeat_work;
 	struct delayed_work		eoc_work;
@@ -1279,6 +1279,28 @@
 }
 EXPORT_SYMBOL(pm8921_is_battery_present);
 
+/*
+ * Disabling the charge current limit causes current
+ * current limits to have no monitoring. An adequate charger
+ * capable of supplying high current while sustaining VIN_MIN
+ * is required if the limiting is disabled.
+ */
+int pm8921_disable_input_current_limit(bool disable)
+{
+	if (!the_chip) {
+		pr_err("called before init\n");
+		return -EINVAL;
+	}
+	if (disable) {
+		pr_warn("Disabling input current limit!\n");
+
+		return pm8xxx_writeb(the_chip->dev->parent,
+			 CHG_BUCK_CTRL_TEST3, 0xF2);
+	}
+	return 0;
+}
+EXPORT_SYMBOL(pm8921_disable_input_current_limit);
+
 int pm8921_set_max_battery_charge_current(int ma)
 {
 	if (!the_chip) {
@@ -1494,18 +1516,20 @@
 static irqreturn_t vbatdet_low_irq_handler(int irq, void *data)
 {
 	struct pm8921_chg_chip *chip = data;
+	int high_transition;
 
-	pm8921_chg_disable_irq(chip, VBATDET_LOW_IRQ);
+	high_transition = pm_chg_get_rt_status(chip, VBATDET_LOW_IRQ);
 
-	/* enable auto charging */
-	pm_chg_auto_enable(chip, !charging_disabled);
+	if (high_transition) {
+		/* enable auto charging */
+		pm_chg_auto_enable(chip, !charging_disabled);
+	}
 	pr_debug("fsm_state=%d\n", pm_chg_get_fsm_state(data));
 
 	power_supply_changed(&chip->batt_psy);
 	power_supply_changed(&chip->usb_psy);
 	power_supply_changed(&chip->dc_psy);
 
-	pm8921_chg_enable_irq(chip, FASTCHG_IRQ);
 	return IRQ_HANDLED;
 }
 
@@ -1561,12 +1585,6 @@
 	chip->bms_notify.is_battery_full = 1;
 	bms_notify_check(chip);
 
-	/*
-	 * since charging is now done, start monitoring for
-	 * battery voltage below resume voltage
-	 */
-	pm8921_chg_enable_irq(chip, VBATDET_LOW_IRQ);
-
 	return IRQ_HANDLED;
 }
 
@@ -1613,14 +1631,17 @@
 static irqreturn_t fastchg_irq_handler(int irq, void *data)
 {
 	struct pm8921_chg_chip *chip = data;
+	int high_transition;
 
-	/* disable this irq now, reenable it when resuming charging */
-	pm8921_chg_disable_irq(chip, FASTCHG_IRQ);
-	power_supply_changed(&chip->batt_psy);
-	wake_lock(&chip->eoc_wake_lock);
-	schedule_delayed_work(&chip->eoc_work,
-			      round_jiffies_relative(msecs_to_jiffies
+	high_transition = pm_chg_get_rt_status(chip, FASTCHG_IRQ);
+	if (high_transition && !delayed_work_pending(&chip->eoc_work)) {
+		wake_lock(&chip->eoc_wake_lock);
+		schedule_delayed_work(&chip->eoc_work,
+				      round_jiffies_relative(msecs_to_jiffies
 						     (EOC_CHECK_PERIOD_MS)));
+	}
+	power_supply_changed(&chip->batt_psy);
+	bms_notify_check(chip);
 	return IRQ_HANDLED;
 }
 
@@ -1834,7 +1855,6 @@
 		pr_debug("fast_chg = %d\n", fast_chg);
 		if (fast_chg == 0) {
 			/* enable fastchg irq */
-			pm8921_chg_enable_irq(chip, FASTCHG_IRQ);
 			count = 0;
 			wake_unlock(&chip->eoc_wake_lock);
 			return;
@@ -1942,48 +1962,69 @@
 
 DECLARE_WORK(btm_config_work, btm_configure_work);
 
+static void set_appropriate_battery_current(struct pm8921_chg_chip *chip)
+{
+	unsigned int chg_current = chip->max_bat_chg_current;
+
+	if (chip->is_bat_cool)
+		chg_current = min(chg_current, chip->cool_bat_chg_current);
+
+	if (chip->is_bat_warm)
+		chg_current = min(chg_current, chip->warm_bat_chg_current);
+
+	if (thermal_mitigation != 0 && !chip->thermal_mitigation)
+		chg_current = min(chg_current,
+				chip->thermal_mitigation[thermal_mitigation]);
+
+	pm_chg_ibatmax_set(the_chip, chg_current);
+}
+
 #define TEMP_HYSTERISIS_DEGC 2
 static void battery_cool(bool enter)
 {
 	pr_debug("enter = %d\n", enter);
+	if (enter == the_chip->is_bat_cool)
+		return;
+	the_chip->is_bat_cool = enter;
 	if (enter) {
 		btm_config.low_thr_temp =
 			the_chip->cool_temp + TEMP_HYSTERISIS_DEGC;
-		pm_chg_ibatmax_set(the_chip, the_chip->cool_bat_chg_current);
+		set_appropriate_battery_current(the_chip);
 		pm_chg_vddmax_set(the_chip, the_chip->cool_bat_voltage);
 		pm_chg_vbatdet_set(the_chip,
 			the_chip->cool_bat_voltage
 			- the_chip->resume_voltage_delta);
 	} else {
 		btm_config.low_thr_temp = the_chip->cool_temp;
-		pm_chg_ibatmax_set(the_chip, the_chip->max_bat_chg_current);
+		set_appropriate_battery_current(the_chip);
 		pm_chg_vddmax_set(the_chip, the_chip->max_voltage);
 		pm_chg_vbatdet_set(the_chip,
 			the_chip->max_voltage - the_chip->resume_voltage_delta);
 	}
-	the_chip->is_bat_cool = enter;
 	schedule_work(&btm_config_work);
 }
 
 static void battery_warm(bool enter)
 {
 	pr_debug("enter = %d\n", enter);
+	if (enter == the_chip->is_bat_warm)
+		return;
+	the_chip->is_bat_warm = enter;
 	if (enter) {
 		btm_config.high_thr_temp =
 			the_chip->warm_temp - TEMP_HYSTERISIS_DEGC;
-		pm_chg_ibatmax_set(the_chip, the_chip->warm_bat_chg_current);
+		set_appropriate_battery_current(the_chip);
 		pm_chg_vddmax_set(the_chip, the_chip->warm_bat_voltage);
 		pm_chg_vbatdet_set(the_chip,
 			the_chip->warm_bat_voltage
 			- the_chip->resume_voltage_delta);
 	} else {
 		btm_config.high_thr_temp = the_chip->warm_temp;
-		pm_chg_ibatmax_set(the_chip, the_chip->max_bat_chg_current);
+		set_appropriate_battery_current(the_chip);
 		pm_chg_vddmax_set(the_chip, the_chip->max_voltage);
 		pm_chg_vbatdet_set(the_chip,
 			the_chip->max_voltage - the_chip->resume_voltage_delta);
 	}
-	the_chip->is_bat_warm = enter;
 	schedule_work(&btm_config_work);
 }
 
@@ -2096,8 +2137,7 @@
 		return -EINVAL;
 	}
 
-	ret = pm_chg_ibatmax_set(chip,
-			chip->thermal_mitigation[thermal_mitigation]);
+	set_appropriate_battery_current(chip);
 	return ret;
 }
 module_param_call(thermal_mitigation, set_therm_mitigation_level,
@@ -2143,6 +2183,7 @@
 	if (usb_chg_current) {
 		/* reissue a vbus draw call */
 		__pm8921_charger_vbus_draw(usb_chg_current);
+		fastchg_irq_handler(chip->pmic_chg_irq[FASTCHG_IRQ], chip);
 	}
 	spin_unlock_irqrestore(&vbus_lock, flags);
 
@@ -2181,7 +2222,8 @@
 	CHG_IRQ(USBIN_OV_IRQ, IRQF_TRIGGER_RISING, usbin_ov_irq_handler),
 	CHG_IRQ(BATT_INSERTED_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 						batt_inserted_irq_handler),
-	CHG_IRQ(VBATDET_LOW_IRQ, IRQF_TRIGGER_HIGH, vbatdet_low_irq_handler),
+	CHG_IRQ(VBATDET_LOW_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+						vbatdet_low_irq_handler),
 	CHG_IRQ(USBIN_UV_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 							usbin_uv_irq_handler),
 	CHG_IRQ(VBAT_OV_IRQ, IRQF_TRIGGER_RISING, vbat_ov_irq_handler),
@@ -2193,7 +2235,8 @@
 	CHG_IRQ(CHGFAIL_IRQ, IRQF_TRIGGER_RISING, chgfail_irq_handler),
 	CHG_IRQ(CHGSTATE_IRQ, IRQF_TRIGGER_RISING, chgstate_irq_handler),
 	CHG_IRQ(LOOP_CHANGE_IRQ, IRQF_TRIGGER_RISING, loop_change_irq_handler),
-	CHG_IRQ(FASTCHG_IRQ, IRQF_TRIGGER_HIGH, fastchg_irq_handler),
+	CHG_IRQ(FASTCHG_IRQ, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+						fastchg_irq_handler),
 	CHG_IRQ(TRKLCHG_IRQ, IRQF_TRIGGER_RISING, trklchg_irq_handler),
 	CHG_IRQ(BATT_REMOVED_IRQ, IRQF_TRIGGER_RISING,
 						batt_removed_irq_handler),
@@ -2298,7 +2341,6 @@
 		return rc;
 	}
 
-	/* TODO needs to be changed as per the temeperature of the battery */
 	rc = pm_chg_ibatmax_set(chip, chip->max_bat_chg_current);
 	if (rc) {
 		pr_err("Failed to set max current to 400 rc=%d\n", rc);
@@ -2438,6 +2480,12 @@
 		pm8xxx_writeb(chip->dev->parent, PSI_CONFIG_STATUS, 0x0C);
 	}
 
+	/* Workarounds for die 3.0 */
+	if (pm8xxx_get_revision(chip->dev->parent) == PM8XXX_REVISION_8921_3p0)
+		pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0xAC);
+
+	pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0xD9);
+
 	/* Disable EOC FSM processing */
 	pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0x91);
 
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 03810ce..a184ab6 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -25,6 +25,44 @@
 
 static struct device_type power_supply_dev_type;
 
+/**
+ * power_supply_set_current_limit - set current limit
+ * @psy:	the power supply to control
+ * @limit:	current limit in uA from the power supply.
+ *		0 will disable the power supply.
+ *
+ * This function will set a maximum supply current from a source
+ * and it will disable the charger when limit is 0.
+ */
+int power_supply_set_current_limit(struct power_supply *psy, int limit)
+{
+	const union power_supply_propval ret = {limit,};
+
+	if (psy->set_property)
+		return psy->set_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX,
+								&ret);
+
+	return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(power_supply_set_current_limit);
+
+/**
+ * power_supply_set_charging_by - set charging state of the charger
+ * @psy:	the power supply to control
+ * @enable:	enables or disables the charger
+ */
+int power_supply_set_charging_by(struct power_supply *psy, bool enable)
+{
+	const union power_supply_propval ret = {enable,};
+
+	if (psy->set_property)
+		return psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE,
+								&ret);
+
+	return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(power_supply_set_charging_by);
+
 static int __power_supply_changed_work(struct device *dev, void *data)
 {
 	struct power_supply *psy = (struct power_supply *)data;
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 6aa111c..90e2687 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -993,8 +993,14 @@
 				e_addr[2] != QC_CHIPID_SL)
 				dev->pgdla = laddr;
 			if (!ret && !pm_runtime_enabled(dev->dev) &&
-				laddr == (QC_MSM_DEVS - 1))
+				laddr == (QC_MSM_DEVS - 1)) {
 				pm_runtime_enable(dev->dev);
+				/*
+				 * Avoid runtime-PM by default, but allow
+				 * command line activation
+				 */
+				pm_runtime_forbid(dev->dev);
+			}
 
 		} else if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
 				mc == SLIM_MSG_MC_REPLY_VALUE) {
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 9ba7d2f..a094b4e 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -1138,7 +1138,7 @@
 		spin_unlock(&port->lock);
 }
 
-static int __init msm_hsl_console_setup(struct console *co, char *options)
+static int msm_hsl_console_setup(struct console *co, char *options)
 {
 	struct uart_port *port;
 	unsigned int vid;
@@ -1201,7 +1201,93 @@
 };
 
 #define MSM_HSL_CONSOLE	(&msm_hsl_console)
+/*
+ * get_console_state - check the per-port serial console state.
+ * @port: uart_port structure describing the port
+ *
+ * Return the state of serial console availability on port.
+ * return 1: If serial console is enabled on particular UART port.
+ * return 0: If serial console is disabled on particular UART port.
+ */
+static int get_console_state(struct uart_port *port)
+{
+	if (is_console(port) && (port->cons->flags & CON_ENABLED))
+		return 1;
+	else
+		return 0;
+}
 
+/* show_msm_console - provide per-port serial console state. */
+static ssize_t show_msm_console(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	int enable;
+	struct uart_port *port;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	port = get_port_from_line(pdev->id);
+
+	enable = get_console_state(port);
+
+	return snprintf(buf, sizeof(enable), "%d\n", enable);
+}
+
+/*
+ * set_msm_console - allow to enable/disable serial console on port.
+ *
+ * writing 1 enables serial console on UART port.
+ * writing 0 disables serial console on UART port.
+ */
+static ssize_t set_msm_console(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	int enable, cur_state;
+	struct uart_port *port;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	port = get_port_from_line(pdev->id);
+
+	cur_state = get_console_state(port);
+	enable = buf[0] - '0';
+
+	if (enable == cur_state)
+		return count;
+
+	switch (enable) {
+	case 0:
+		pr_debug("%s(): Calling stop_console\n", __func__);
+		console_stop(port->cons);
+		pr_debug("%s(): Calling unregister_console\n", __func__);
+		unregister_console(port->cons);
+		pm_runtime_put_sync(&pdev->dev);
+		pm_runtime_disable(&pdev->dev);
+		/*
+		 * Disable UART Core clk
+		 * 3 - to disable the UART clock
+		 * Thid parameter is not used here, but used in serial core.
+		 */
+		msm_hsl_power(port, 3, 1);
+		break;
+	case 1:
+		pr_debug("%s(): Calling register_console\n", __func__);
+		/*
+		 * Disable UART Core clk
+		 * 0 - to enable the UART clock
+		 * Thid parameter is not used here, but used in serial core.
+		 */
+		msm_hsl_power(port, 0, 1);
+		pm_runtime_enable(&pdev->dev);
+		register_console(port->cons);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return count;
+}
+static DEVICE_ATTR(console, S_IWUSR | S_IRUGO, show_msm_console,
+						set_msm_console);
 #else
 #define MSM_HSL_CONSOLE	NULL
 #endif
@@ -1286,6 +1372,11 @@
 	device_set_wakeup_capable(&pdev->dev, 1);
 	platform_set_drvdata(pdev, port);
 	pm_runtime_enable(port->dev);
+#ifdef CONFIG_SERIAL_MSM_HSL_CONSOLE
+	ret = device_create_file(&pdev->dev, &dev_attr_console);
+	if (unlikely(ret))
+		pr_err("%s():Can't create console attribute\n", __func__);
+#endif
 	msm_hsl_debugfs_init(msm_hsl_port, pdev->id);
 
 	/* Temporarily increase the refcount on the GSBI clock to avoid a race
@@ -1305,6 +1396,9 @@
 	struct uart_port *port;
 
 	port = get_port_from_line(pdev->id);
+#ifdef CONFIG_SERIAL_MSM_HSL_CONSOLE
+	device_remove_file(&pdev->dev, &dev_attr_console);
+#endif
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 117d3bf..94ed950 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -1089,6 +1089,12 @@
 	 This csw hack feature is for increasing the performance of the mass
 	 storage
 
+config USB_MSC_PROFILING
+	bool "USB MSC performance profiling"
+	help
+	  If you say Y here, support will be added for collecting
+	  Mass-storage performance numbers at the VFS level.
+
 config MODEM_SUPPORT
 	boolean "modem support in generic serial function driver"
 	depends on USB_G_ANDROID
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 1e3beac..af6f351 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -62,6 +62,7 @@
 #include "f_serial.c"
 //#include "f_acm.c"
 #include "f_adb.c"
+#include "f_ccid.c"
 #include "f_mtp.c"
 #include "f_accessory.c"
 #define USB_ETH_RNDIS y
@@ -498,6 +499,31 @@
 	.bind_config	= adb_function_bind_config,
 };
 
+/* CCID */
+static int ccid_function_init(struct android_usb_function *f,
+					struct usb_composite_dev *cdev)
+{
+	return ccid_setup();
+}
+
+static void ccid_function_cleanup(struct android_usb_function *f)
+{
+	ccid_cleanup();
+}
+
+static int ccid_function_bind_config(struct android_usb_function *f,
+						struct usb_configuration *c)
+{
+	return ccid_bind_config(c);
+}
+
+static struct android_usb_function ccid_function = {
+	.name		= "ccid",
+	.init		= ccid_function_init,
+	.cleanup	= ccid_function_cleanup,
+	.bind_config	= ccid_function_bind_config,
+};
+
 #if 0
 #define MAX_ACM_INSTANCES 4
 struct acm_function_config {
@@ -941,6 +967,7 @@
 	&diag_function,
 	&serial_function,
 	&adb_function,
+	&ccid_function,
 //	&acm_function,
 	&mtp_function,
 	&ptp_function,
@@ -1063,6 +1090,32 @@
 /*-------------------------------------------------------------------------*/
 /* /sys/class/android_usb/android%d/ interface */
 
+static ssize_t remote_wakeup_show(struct device *pdev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			!!(android_config_driver.bmAttributes &
+				USB_CONFIG_ATT_WAKEUP));
+}
+
+static ssize_t remote_wakeup_store(struct device *pdev,
+		struct device_attribute *attr, const char *buff, size_t size)
+{
+	int enable = 0;
+
+	sscanf(buff, "%d", &enable);
+
+	pr_debug("android_usb: %s remote wakeup\n",
+			enable ? "enabling" : "disabling");
+
+	if (enable)
+		android_config_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	else
+		android_config_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
+
+	return size;
+}
+
 static ssize_t
 functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
 {
@@ -1218,6 +1271,8 @@
 static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show, functions_store);
 static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
 static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
+static DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR,
+		remote_wakeup_show, remote_wakeup_store);
 
 static struct device_attribute *android_usb_attributes[] = {
 	&dev_attr_idVendor,
@@ -1232,6 +1287,7 @@
 	&dev_attr_functions,
 	&dev_attr_enable,
 	&dev_attr_state,
+	&dev_attr_remote_wakeup,
 	NULL
 };
 
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 17fe820..e084278 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2773,6 +2773,7 @@
 	unsigned long flags;
 	int i, j;
 	int retval = -ENOMEM;
+	bool put = false;
 
 	trace("%p", driver);
 
@@ -2877,18 +2878,21 @@
 			if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
 				hw_device_reset(udc);
 		} else {
+			put = true;
 			goto done;
 		}
 	}
 
-	if (!udc->softconnect)
+	if (!udc->softconnect) {
+		put = true;
 		goto done;
+	}
 
 	retval = hw_device_state(udc->ep0out.qh.dma);
 
  done:
 	spin_unlock_irqrestore(udc->lock, flags);
-	if (retval)
+	if (retval || put)
 		pm_runtime_put_sync(&udc->gadget.dev);
 	return retval;
 }
diff --git a/drivers/usb/gadget/f_ccid.c b/drivers/usb/gadget/f_ccid.c
new file mode 100644
index 0000000..a11f439
--- /dev/null
+++ b/drivers/usb/gadget/f_ccid.c
@@ -0,0 +1,1014 @@
+/*
+ * f_ccid.c -- CCID function Driver
+ *
+ * Copyright (c) 2011, 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/slab.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/usb/android_composite.h>
+#include <linux/fs.h>
+#include <linux/usb/ccid_desc.h>
+#include <linux/miscdevice.h>
+
+#include "f_ccid.h"
+
+#define BULK_IN_BUFFER_SIZE sizeof(struct ccid_bulk_in_header)
+#define BULK_OUT_BUFFER_SIZE sizeof(struct ccid_bulk_out_header)
+#define CTRL_BUF_SIZE	4
+#define FUNCTION_NAME	"ccid"
+#define CCID_NOTIFY_INTERVAL	5
+#define CCID_NOTIFY_MAXPACKET	4
+
+/* number of tx requests to allocate */
+#define TX_REQ_MAX 4
+
+struct ccid_descs {
+	struct usb_endpoint_descriptor *in;
+	struct usb_endpoint_descriptor *out;
+	struct usb_endpoint_descriptor *notify;
+};
+
+struct ccid_ctrl_dev {
+	atomic_t opened;
+	struct list_head tx_q;
+	wait_queue_head_t tx_wait_q;
+	unsigned char buf[CTRL_BUF_SIZE];
+	int tx_ctrl_done;
+};
+
+struct ccid_bulk_dev {
+	atomic_t error;
+	atomic_t opened;
+	atomic_t rx_req_busy;
+	wait_queue_head_t read_wq;
+	wait_queue_head_t write_wq;
+	struct usb_request *rx_req;
+	int rx_done;
+	struct list_head tx_idle;
+};
+
+struct f_ccid {
+	struct usb_function function;
+	struct usb_composite_dev *cdev;
+	int ifc_id;
+	spinlock_t lock;
+	atomic_t online;
+	/* usb descriptors */
+	struct ccid_descs fs;
+	struct ccid_descs hs;
+	/* usb eps*/
+	struct usb_ep *notify;
+	struct usb_ep *in;
+	struct usb_ep *out;
+	struct usb_endpoint_descriptor *in_desc;
+	struct usb_endpoint_descriptor *out_desc;
+	struct usb_endpoint_descriptor *notify_desc;
+	struct usb_request *notify_req;
+	struct ccid_ctrl_dev ctrl_dev;
+	struct ccid_bulk_dev bulk_dev;
+	int dtr_state;
+};
+
+static struct f_ccid *_ccid_dev;
+static struct miscdevice ccid_bulk_device;
+static struct miscdevice ccid_ctrl_device;
+
+/* Interface Descriptor: */
+static struct usb_interface_descriptor ccid_interface_desc = {
+	.bLength =		USB_DT_INTERFACE_SIZE,
+	.bDescriptorType =	USB_DT_INTERFACE,
+	.bNumEndpoints =	3,
+	.bInterfaceClass =	USB_CLASS_CSCID,
+	.bInterfaceSubClass =	0,
+	.bInterfaceProtocol =	0,
+};
+/* CCID Class Descriptor */
+static struct usb_ccid_class_descriptor ccid_class_desc = {
+	.bLength =		sizeof(ccid_class_desc),
+	.bDescriptorType =	CCID_DECRIPTOR_TYPE,
+	.bcdCCID =		CCID1_10,
+	.bMaxSlotIndex =	0,
+	/* This value indicates what voltages the CCID can supply to slots */
+	.bVoltageSupport =	VOLTS_3_0,
+	.dwProtocols =		PROTOCOL_TO,
+	/* Default ICC clock frequency in KHz */
+	.dwDefaultClock =	3580,
+	/* Maximum supported ICC clock frequency in KHz */
+	.dwMaximumClock =	3580,
+	.bNumClockSupported =	0,
+	/* Default ICC I/O data rate in bps */
+	.dwDataRate =		9600,
+	/* Maximum supported ICC I/O data rate in bps */
+	.dwMaxDataRate =	9600,
+	.bNumDataRatesSupported = 0,
+	.dwMaxIFSD =		0,
+	.dwSynchProtocols =	0,
+	.dwMechanical =		0,
+	/* This value indicates what intelligent features the CCID has */
+	.dwFeatures =		CCID_FEATURES_EXC_SAPDU |
+				CCID_FEATURES_AUTO_PNEGO |
+				CCID_FEATURES_AUTO_BAUD |
+				CCID_FEATURES_AUTO_CLOCK |
+				CCID_FEATURES_AUTO_VOLT |
+				CCID_FEATURES_AUTO_ACTIV |
+				CCID_FEATURES_AUTO_PCONF,
+	/* extended APDU level Message Length */
+	.dwMaxCCIDMessageLength = 0x200,
+	.bClassGetResponse =	0x0,
+	.bClassEnvelope =	0x0,
+	.wLcdLayout =		0,
+	.bPINSupport =		0,
+	.bMaxCCIDBusySlots =	1
+};
+/* Full speed support: */
+static struct usb_endpoint_descriptor ccid_fs_notify_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	__constant_cpu_to_le16(CCID_NOTIFY_MAXPACKET),
+	.bInterval =		1 << CCID_NOTIFY_INTERVAL,
+};
+
+static struct usb_endpoint_descriptor ccid_fs_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize   =	__constant_cpu_to_le16(64),
+};
+
+static struct usb_endpoint_descriptor ccid_fs_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+	.bEndpointAddress =	USB_DIR_OUT,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize   =	 __constant_cpu_to_le16(64),
+};
+
+static struct usb_descriptor_header *ccid_fs_descs[] = {
+	(struct usb_descriptor_header *) &ccid_interface_desc,
+	(struct usb_descriptor_header *) &ccid_class_desc,
+	(struct usb_descriptor_header *) &ccid_fs_notify_desc,
+	(struct usb_descriptor_header *) &ccid_fs_in_desc,
+	(struct usb_descriptor_header *) &ccid_fs_out_desc,
+	NULL,
+};
+
+/* High speed support: */
+static struct usb_endpoint_descriptor ccid_hs_notify_desc  = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	__constant_cpu_to_le16(CCID_NOTIFY_MAXPACKET),
+	.bInterval =		CCID_NOTIFY_INTERVAL + 4,
+};
+
+static struct usb_endpoint_descriptor ccid_hs_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor ccid_hs_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+	.bEndpointAddress =	USB_DIR_OUT,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *ccid_hs_descs[] = {
+	(struct usb_descriptor_header *) &ccid_interface_desc,
+	(struct usb_descriptor_header *) &ccid_class_desc,
+	(struct usb_descriptor_header *) &ccid_hs_notify_desc,
+	(struct usb_descriptor_header *) &ccid_hs_in_desc,
+	(struct usb_descriptor_header *) &ccid_hs_out_desc,
+	NULL,
+};
+
+static inline struct f_ccid *func_to_ccid(struct usb_function *f)
+{
+	return container_of(f, struct f_ccid, function);
+}
+
+static void ccid_req_put(struct f_ccid *ccid_dev, struct list_head *head,
+		struct usb_request *req)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ccid_dev->lock, flags);
+	list_add_tail(&req->list, head);
+	spin_unlock_irqrestore(&ccid_dev->lock, flags);
+}
+
+static struct usb_request *ccid_req_get(struct f_ccid *ccid_dev,
+					struct list_head *head)
+{
+	unsigned long flags;
+	struct usb_request *req = NULL;
+
+	spin_lock_irqsave(&ccid_dev->lock, flags);
+	if (!list_empty(head)) {
+		req = list_first_entry(head, struct usb_request, list);
+		list_del(&req->list);
+	}
+	spin_unlock_irqrestore(&ccid_dev->lock, flags);
+	return req;
+}
+
+static void ccid_notify_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	switch (req->status) {
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+	case 0:
+		break;
+	default:
+		pr_err("CCID notify ep error %d\n", req->status);
+	}
+}
+
+static void ccid_bulk_complete_in(struct usb_ep *ep, struct usb_request *req)
+{
+	struct f_ccid *ccid_dev = _ccid_dev;
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+
+	if (req->status != 0)
+		atomic_set(&bulk_dev->error, 1);
+
+	ccid_req_put(ccid_dev, &bulk_dev->tx_idle, req);
+	wake_up(&bulk_dev->write_wq);
+}
+
+static void ccid_bulk_complete_out(struct usb_ep *ep, struct usb_request *req)
+{
+	struct f_ccid *ccid_dev = _ccid_dev;
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+	if (req->status != 0)
+		atomic_set(&bulk_dev->error, 1);
+
+	bulk_dev->rx_done = 1;
+	wake_up(&bulk_dev->read_wq);
+}
+
+static struct usb_request *
+ccid_request_alloc(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags)
+{
+	struct usb_request *req;
+
+	req = usb_ep_alloc_request(ep, kmalloc_flags);
+
+	if (req != NULL) {
+		req->length = len;
+		req->buf = kmalloc(len, kmalloc_flags);
+		if (req->buf == NULL) {
+			usb_ep_free_request(ep, req);
+			req = NULL;
+		}
+	}
+
+	return req ? req : ERR_PTR(-ENOMEM);
+}
+
+static void ccid_request_free(struct usb_request *req, struct usb_ep *ep)
+{
+	if (req) {
+		kfree(req->buf);
+		usb_ep_free_request(ep, req);
+	}
+}
+
+static int
+ccid_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
+{
+	struct f_ccid *ccid_dev = container_of(f, struct f_ccid, function);
+	struct ccid_ctrl_dev *ctrl_dev = &ccid_dev->ctrl_dev;
+	struct usb_composite_dev *cdev = f->config->cdev;
+	struct usb_request      *req = cdev->req;
+	int ret = -EOPNOTSUPP;
+	u16 w_index = le16_to_cpu(ctrl->wIndex);
+	u16 w_value = le16_to_cpu(ctrl->wValue);
+	u16 w_length = le16_to_cpu(ctrl->wLength);
+
+	if (!atomic_read(&ccid_dev->online))
+		return -ENOTCONN;
+
+	switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
+
+	case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+			| CCIDGENERICREQ_ABORT:
+		if (w_length != 0)
+			goto invalid;
+		ctrl_dev->buf[0] = CCIDGENERICREQ_ABORT;
+		ctrl_dev->buf[1] = w_value & 0xFF;
+		ctrl_dev->buf[2] = (w_value >> 8) & 0xFF;
+		ctrl_dev->buf[3] = 0x00;
+		ctrl_dev->tx_ctrl_done = 1;
+		wake_up(&ctrl_dev->tx_wait_q);
+		return 0;
+
+	case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+			| CCIDGENERICREQ_GET_CLOCK_FREQUENCIES:
+		if (w_length > req->length)
+			goto invalid;
+		*(u32 *) req->buf =
+				cpu_to_le32(ccid_class_desc.dwDefaultClock);
+		ret = min_t(u32, w_length,
+				sizeof(ccid_class_desc.dwDefaultClock));
+		break;
+
+	case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8)
+			| CCIDGENERICREQ_GET_DATA_RATES:
+		if (w_length > req->length)
+			goto invalid;
+		*(u32 *) req->buf = cpu_to_le32(ccid_class_desc.dwDataRate);
+		ret = min_t(u32, w_length, sizeof(ccid_class_desc.dwDataRate));
+		break;
+
+	default:
+invalid:
+	pr_debug("invalid control req%02x.%02x v%04x i%04x l%d\n",
+		ctrl->bRequestType, ctrl->bRequest,
+		w_value, w_index, w_length);
+	}
+
+	/* respond with data transfer or status phase? */
+	if (ret >= 0) {
+		pr_debug("ccid req%02x.%02x v%04x i%04x l%d\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			w_value, w_index, w_length);
+		req->length = ret;
+		ret = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
+		if (ret < 0)
+			pr_err("ccid ep0 enqueue err %d\n", ret);
+	}
+
+	return ret;
+}
+
+static void ccid_function_disable(struct usb_function *f)
+{
+	struct f_ccid *ccid_dev = func_to_ccid(f);
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+	struct ccid_ctrl_dev *ctrl_dev = &ccid_dev->ctrl_dev;
+	struct usb_request *req;
+
+	/* Disable endpoints */
+	usb_ep_disable(ccid_dev->notify);
+	usb_ep_disable(ccid_dev->in);
+	usb_ep_disable(ccid_dev->out);
+	/* Free endpoint related requests */
+	ccid_request_free(ccid_dev->notify_req, ccid_dev->notify);
+	if (!atomic_read(&bulk_dev->rx_req_busy))
+		ccid_request_free(bulk_dev->rx_req, ccid_dev->out);
+	while ((req = ccid_req_get(ccid_dev, &bulk_dev->tx_idle)))
+		ccid_request_free(req, ccid_dev->in);
+
+	ccid_dev->dtr_state = 0;
+	atomic_set(&ccid_dev->online, 0);
+	/* Wake up threads */
+	wake_up(&bulk_dev->write_wq);
+	wake_up(&bulk_dev->read_wq);
+	wake_up(&ctrl_dev->tx_wait_q);
+
+}
+
+static int
+ccid_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+	struct f_ccid *ccid_dev = func_to_ccid(f);
+	struct usb_composite_dev *cdev = ccid_dev->cdev;
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+	struct usb_request *req;
+	int ret = 0;
+	int i;
+
+	ccid_dev->notify_req = ccid_request_alloc(ccid_dev->notify,
+			sizeof(struct usb_ccid_notification), GFP_ATOMIC);
+	if (IS_ERR(ccid_dev->notify_req)) {
+		pr_err("%s: unable to allocate memory for notify req\n",
+				__func__);
+		return PTR_ERR(ccid_dev->notify_req);
+	}
+	ccid_dev->notify_req->complete = ccid_notify_complete;
+	ccid_dev->notify_req->context = ccid_dev;
+
+	/* now allocate requests for our endpoints */
+	req = ccid_request_alloc(ccid_dev->out, BULK_OUT_BUFFER_SIZE,
+							GFP_ATOMIC);
+	if (IS_ERR(req)) {
+		pr_err("%s: unable to allocate memory for out req\n",
+				__func__);
+		ret = PTR_ERR(req);
+		goto free_notify;
+	}
+	req->complete = ccid_bulk_complete_out;
+	req->context = ccid_dev;
+	bulk_dev->rx_req = req;
+
+	for (i = 0; i < TX_REQ_MAX; i++) {
+		req = ccid_request_alloc(ccid_dev->in, BULK_IN_BUFFER_SIZE,
+								GFP_ATOMIC);
+		if (IS_ERR(req)) {
+			pr_err("%s: unable to allocate memory for in req\n",
+					__func__);
+			ret = PTR_ERR(req);
+			goto free_bulk_out;
+		}
+		req->complete = ccid_bulk_complete_in;
+		req->context = ccid_dev;
+		ccid_req_put(ccid_dev, &bulk_dev->tx_idle, req);
+	}
+
+	/* choose the descriptors and enable endpoints */
+	ccid_dev->notify_desc = ep_choose(cdev->gadget,
+				ccid_dev->hs.notify,
+				ccid_dev->fs.notify);
+	ret = usb_ep_enable(ccid_dev->notify, ccid_dev->notify_desc);
+	if (ret) {
+		pr_err("%s: usb ep#%s enable failed, err#%d\n",
+				__func__, ccid_dev->notify->name, ret);
+		goto free_bulk_in;
+	}
+	ccid_dev->notify->driver_data = ccid_dev;
+
+	ccid_dev->in_desc = ep_choose(cdev->gadget,
+			ccid_dev->hs.in, ccid_dev->fs.in);
+	ret = usb_ep_enable(ccid_dev->in, ccid_dev->in_desc);
+	if (ret) {
+		pr_err("%s: usb ep#%s enable failed, err#%d\n",
+				__func__, ccid_dev->in->name, ret);
+		goto disable_ep_notify;
+	}
+
+	ccid_dev->out_desc = ep_choose(cdev->gadget,
+			ccid_dev->hs.out, ccid_dev->fs.out);
+	ret = usb_ep_enable(ccid_dev->out, ccid_dev->out_desc);
+	if (ret) {
+		pr_err("%s: usb ep#%s enable failed, err#%d\n",
+				__func__, ccid_dev->out->name, ret);
+		goto disable_ep_in;
+	}
+	ccid_dev->dtr_state = 1;
+	atomic_set(&ccid_dev->online, 1);
+	return ret;
+
+disable_ep_in:
+	usb_ep_disable(ccid_dev->in);
+disable_ep_notify:
+	usb_ep_disable(ccid_dev->notify);
+	ccid_dev->notify->driver_data = NULL;
+free_bulk_in:
+	while ((req = ccid_req_get(ccid_dev, &bulk_dev->tx_idle)))
+		ccid_request_free(req, ccid_dev->in);
+free_bulk_out:
+	ccid_request_free(bulk_dev->rx_req, ccid_dev->out);
+free_notify:
+	ccid_request_free(ccid_dev->notify_req, ccid_dev->notify);
+	return ret;
+}
+
+static void ccid_function_unbind(struct usb_configuration *c,
+					struct usb_function *f)
+{
+	if (gadget_is_dualspeed(c->cdev->gadget))
+		usb_free_descriptors(f->hs_descriptors);
+	usb_free_descriptors(f->descriptors);
+
+}
+
+static int ccid_function_bind(struct usb_configuration *c,
+					struct usb_function *f)
+{
+	struct f_ccid *ccid_dev = func_to_ccid(f);
+	struct usb_ep *ep;
+	struct usb_composite_dev *cdev = c->cdev;
+	int ret = -ENODEV;
+
+	ccid_dev->ifc_id = usb_interface_id(c, f);
+	if (ccid_dev->ifc_id < 0) {
+		pr_err("%s: unable to allocate ifc id, err:%d",
+				__func__, ccid_dev->ifc_id);
+		return ccid_dev->ifc_id;
+	}
+	ccid_interface_desc.bInterfaceNumber = ccid_dev->ifc_id;
+
+	ep = usb_ep_autoconfig(cdev->gadget, &ccid_fs_notify_desc);
+	if (!ep) {
+		pr_err("%s: usb epnotify autoconfig failed\n", __func__);
+		return -ENODEV;
+	}
+	ccid_dev->notify = ep;
+	ep->driver_data = cdev;
+
+	ep = usb_ep_autoconfig(cdev->gadget, &ccid_fs_in_desc);
+	if (!ep) {
+		pr_err("%s: usb epin autoconfig failed\n", __func__);
+		ret = -ENODEV;
+		goto ep_auto_in_fail;
+	}
+	ccid_dev->in = ep;
+	ep->driver_data = cdev;
+
+	ep = usb_ep_autoconfig(cdev->gadget, &ccid_fs_out_desc);
+	if (!ep) {
+		pr_err("%s: usb epout autoconfig failed\n", __func__);
+		ret = -ENODEV;
+		goto ep_auto_out_fail;
+	}
+	ccid_dev->out = ep;
+	ep->driver_data = cdev;
+
+	f->descriptors = usb_copy_descriptors(ccid_fs_descs);
+	if (!f->descriptors)
+		goto ep_auto_out_fail;
+
+	ccid_dev->fs.in = usb_find_endpoint(ccid_fs_descs,
+					f->descriptors,
+					&ccid_fs_in_desc);
+	ccid_dev->fs.out = usb_find_endpoint(ccid_fs_descs,
+					f->descriptors,
+					&ccid_fs_out_desc);
+	ccid_dev->fs.notify = usb_find_endpoint(ccid_fs_descs,
+					f->descriptors,
+					&ccid_fs_notify_desc);
+
+	if (gadget_is_dualspeed(cdev->gadget)) {
+		ccid_hs_in_desc.bEndpointAddress =
+				ccid_fs_in_desc.bEndpointAddress;
+		ccid_hs_out_desc.bEndpointAddress =
+				ccid_fs_out_desc.bEndpointAddress;
+		ccid_hs_notify_desc.bEndpointAddress =
+				ccid_fs_notify_desc.bEndpointAddress;
+
+		/* copy descriptors, and track endpoint copies */
+		f->hs_descriptors = usb_copy_descriptors(ccid_hs_descs);
+		if (!f->hs_descriptors)
+			goto ep_auto_out_fail;
+
+		ccid_dev->hs.in = usb_find_endpoint(ccid_hs_descs,
+				f->hs_descriptors, &ccid_hs_in_desc);
+		ccid_dev->hs.out = usb_find_endpoint(ccid_hs_descs,
+				f->hs_descriptors, &ccid_hs_out_desc);
+		ccid_dev->hs.notify = usb_find_endpoint(ccid_hs_descs,
+				f->hs_descriptors, &ccid_hs_notify_desc);
+	}
+
+	pr_debug("%s: CCID %s Speed, IN:%s OUT:%s\n", __func__,
+			gadget_is_dualspeed(cdev->gadget) ? "dual" : "full",
+			ccid_dev->in->name, ccid_dev->out->name);
+
+	return 0;
+
+ep_auto_out_fail:
+	ccid_dev->out->driver_data = NULL;
+	ccid_dev->out = NULL;
+ep_auto_in_fail:
+	ccid_dev->in->driver_data = NULL;
+	ccid_dev->in = NULL;
+
+	return ret;
+}
+
+static int ccid_bulk_open(struct inode *ip, struct file *fp)
+{
+	struct f_ccid *ccid_dev = _ccid_dev;
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+	unsigned long flags;
+
+	pr_debug("ccid_bulk_open\n");
+	if (!atomic_read(&ccid_dev->online)) {
+		pr_debug("%s: USB cable not connected\n", __func__);
+		return -ENODEV;
+	}
+
+	if (atomic_read(&bulk_dev->opened)) {
+		pr_debug("%s: bulk device is already opened\n", __func__);
+		return -EBUSY;
+	}
+	atomic_set(&bulk_dev->opened, 1);
+	/* clear the error latch */
+	atomic_set(&bulk_dev->error, 0);
+	spin_lock_irqsave(&ccid_dev->lock, flags);
+	fp->private_data = ccid_dev;
+	spin_unlock_irqrestore(&ccid_dev->lock, flags);
+
+	return 0;
+}
+
+static int ccid_bulk_release(struct inode *ip, struct file *fp)
+{
+	struct f_ccid *ccid_dev =  fp->private_data;
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+
+	pr_debug("ccid_bulk_release\n");
+	atomic_set(&bulk_dev->opened, 0);
+	return 0;
+}
+
+static ssize_t ccid_bulk_read(struct file *fp, char __user *buf,
+				size_t count, loff_t *pos)
+{
+	struct f_ccid *ccid_dev =  fp->private_data;
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+	struct usb_request *req;
+	int r = count, xfer;
+	int ret;
+	unsigned long flags;
+
+	pr_debug("ccid_bulk_read(%d)\n", count);
+
+	if (count > BULK_OUT_BUFFER_SIZE) {
+		pr_err("%s: max_buffer_size:%d given_pkt_size:%d\n",
+				__func__, BULK_OUT_BUFFER_SIZE, count);
+		return -ENOMEM;
+	}
+
+	if (atomic_read(&bulk_dev->error)) {
+		r = -EIO;
+		pr_err("%s bulk_dev_error\n", __func__);
+		goto done;
+	}
+
+requeue_req:
+	spin_lock_irqsave(&ccid_dev->lock, flags);
+	if (!atomic_read(&ccid_dev->online)) {
+		pr_debug("%s: USB cable not connected\n", __func__);
+		return -ENODEV;
+	}
+	/* queue a request */
+	req = bulk_dev->rx_req;
+	req->length = count;
+	bulk_dev->rx_done = 0;
+	spin_unlock_irqrestore(&ccid_dev->lock, flags);
+	ret = usb_ep_queue(ccid_dev->out, req, GFP_KERNEL);
+	if (ret < 0) {
+		r = -EIO;
+		pr_err("%s usb ep queue failed\n", __func__);
+		atomic_set(&bulk_dev->error, 1);
+		goto done;
+	}
+	/* wait for a request to complete */
+	ret = wait_event_interruptible(bulk_dev->read_wq, bulk_dev->rx_done ||
+					atomic_read(&bulk_dev->error) ||
+					!atomic_read(&ccid_dev->online));
+	if (ret < 0) {
+		atomic_set(&bulk_dev->error, 1);
+		r = ret;
+		usb_ep_dequeue(ccid_dev->out, req);
+		goto done;
+	}
+	if (!atomic_read(&bulk_dev->error)) {
+		spin_lock_irqsave(&ccid_dev->lock, flags);
+		if (!atomic_read(&ccid_dev->online)) {
+			spin_unlock_irqrestore(&ccid_dev->lock, flags);
+			pr_debug("%s: USB cable not connected\n", __func__);
+			r = -ENODEV;
+			goto done;
+		}
+		/* If we got a 0-len packet, throw it back and try again. */
+		if (req->actual == 0) {
+			spin_unlock_irqrestore(&ccid_dev->lock, flags);
+			goto requeue_req;
+		}
+		xfer = (req->actual < count) ? req->actual : count;
+		atomic_set(&bulk_dev->rx_req_busy, 1);
+		spin_unlock_irqrestore(&ccid_dev->lock, flags);
+
+		if (copy_to_user(buf, req->buf, xfer))
+			r = -EFAULT;
+
+		spin_lock_irqsave(&ccid_dev->lock, flags);
+		atomic_set(&bulk_dev->rx_req_busy, 0);
+		if (!atomic_read(&ccid_dev->online)) {
+			ccid_request_free(bulk_dev->rx_req, ccid_dev->out);
+			spin_unlock_irqrestore(&ccid_dev->lock, flags);
+			pr_debug("%s: USB cable not connected\n", __func__);
+			r = -ENODEV;
+			goto done;
+		}
+		spin_unlock_irqrestore(&ccid_dev->lock, flags);
+	} else {
+		r = -EIO;
+	}
+done:
+	pr_debug("ccid_bulk_read returning %d\n", r);
+	return r;
+}
+
+static ssize_t ccid_bulk_write(struct file *fp, const char __user *buf,
+				 size_t count, loff_t *pos)
+{
+	struct f_ccid *ccid_dev =  fp->private_data;
+	struct ccid_bulk_dev *bulk_dev = &ccid_dev->bulk_dev;
+	struct usb_request *req = 0;
+	int r = count;
+	int ret;
+	unsigned long flags;
+
+	pr_debug("ccid_bulk_write(%d)\n", count);
+
+	if (!atomic_read(&ccid_dev->online)) {
+		pr_debug("%s: USB cable not connected\n", __func__);
+		return -ENODEV;
+	}
+
+	if (!count) {
+		pr_err("%s: zero length ctrl pkt\n", __func__);
+		return -ENODEV;
+	}
+	if (count > BULK_IN_BUFFER_SIZE) {
+		pr_err("%s: max_buffer_size:%d given_pkt_size:%d\n",
+				__func__, BULK_IN_BUFFER_SIZE, count);
+		return -ENOMEM;
+	}
+
+
+	/* get an idle tx request to use */
+	ret = wait_event_interruptible(bulk_dev->write_wq,
+		((req = ccid_req_get(ccid_dev, &bulk_dev->tx_idle)) ||
+		 atomic_read(&bulk_dev->error)));
+
+	if (ret < 0) {
+		r = ret;
+		goto done;
+	}
+
+	if (atomic_read(&bulk_dev->error)) {
+		pr_err(" %s dev->error\n", __func__);
+		r = -EIO;
+		goto done;
+	}
+	if (copy_from_user(req->buf, buf, count)) {
+		if (!atomic_read(&ccid_dev->online)) {
+			pr_debug("%s: USB cable not connected\n",
+						__func__);
+			ccid_request_free(req, ccid_dev->in);
+			r = -ENODEV;
+		} else {
+			ccid_req_put(ccid_dev, &bulk_dev->tx_idle, req);
+			r = -EFAULT;
+		}
+		goto done;
+	}
+	req->length = count;
+	ret = usb_ep_queue(ccid_dev->in, req, GFP_KERNEL);
+	if (ret < 0) {
+		pr_debug("ccid_bulk_write: xfer error %d\n", ret);
+		atomic_set(&bulk_dev->error, 1);
+		ccid_req_put(ccid_dev, &bulk_dev->tx_idle, req);
+		r = -EIO;
+		spin_lock_irqsave(&ccid_dev->lock, flags);
+		if (!atomic_read(&ccid_dev->online)) {
+			spin_unlock_irqrestore(&ccid_dev->lock, flags);
+			pr_debug("%s: USB cable not connected\n",
+							__func__);
+			while ((req = ccid_req_get(ccid_dev,
+						&bulk_dev->tx_idle)))
+				ccid_request_free(req, ccid_dev->in);
+			r = -ENODEV;
+		}
+		spin_unlock_irqrestore(&ccid_dev->lock, flags);
+		goto done;
+	}
+done:
+	pr_debug("ccid_bulk_write returning %d\n", r);
+	return r;
+}
+
+static const struct file_operations ccid_bulk_fops = {
+	.owner = THIS_MODULE,
+	.read = ccid_bulk_read,
+	.write = ccid_bulk_write,
+	.open = ccid_bulk_open,
+	.release = ccid_bulk_release,
+};
+
+static struct miscdevice ccid_bulk_device = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "ccid_bulk",
+	.fops = &ccid_bulk_fops,
+};
+
+static int ccid_bulk_device_init(struct f_ccid *dev)
+{
+	int ret;
+	struct ccid_bulk_dev *bulk_dev = &dev->bulk_dev;
+
+	init_waitqueue_head(&bulk_dev->read_wq);
+	init_waitqueue_head(&bulk_dev->write_wq);
+	INIT_LIST_HEAD(&bulk_dev->tx_idle);
+
+	ret = misc_register(&ccid_bulk_device);
+	if (ret) {
+		pr_err("%s: failed to register misc device\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ccid_ctrl_open(struct inode *inode, struct file *fp)
+{
+	struct f_ccid *ccid_dev =  _ccid_dev;
+	struct ccid_ctrl_dev *ctrl_dev = &ccid_dev->ctrl_dev;
+	unsigned long flags;
+
+	if (!atomic_read(&ccid_dev->online)) {
+		pr_debug("%s: USB cable not connected\n", __func__);
+		return -ENODEV;
+	}
+	if (atomic_read(&ctrl_dev->opened)) {
+		pr_debug("%s: ctrl device is already opened\n", __func__);
+		return -EBUSY;
+	}
+	atomic_set(&ctrl_dev->opened, 1);
+	spin_lock_irqsave(&ccid_dev->lock, flags);
+	fp->private_data = ccid_dev;
+	spin_unlock_irqrestore(&ccid_dev->lock, flags);
+
+	return 0;
+}
+
+
+static int ccid_ctrl_release(struct inode *inode, struct file *fp)
+{
+	struct f_ccid *ccid_dev = fp->private_data;
+	struct ccid_ctrl_dev *ctrl_dev = &ccid_dev->ctrl_dev;
+
+	atomic_set(&ctrl_dev->opened, 0);
+
+	return 0;
+}
+
+static ssize_t ccid_ctrl_read(struct file *fp, char __user *buf,
+		      size_t count, loff_t *ppos)
+{
+	struct f_ccid *ccid_dev = fp->private_data;
+	struct ccid_ctrl_dev *ctrl_dev = &ccid_dev->ctrl_dev;
+	int ret = 0;
+
+	if (!atomic_read(&ccid_dev->online)) {
+		pr_debug("%s: USB cable not connected\n", __func__);
+		return -ENODEV;
+	}
+	if (count > CTRL_BUF_SIZE)
+		count = CTRL_BUF_SIZE;
+
+	ret = wait_event_interruptible(ctrl_dev->tx_wait_q,
+					 ctrl_dev->tx_ctrl_done);
+	if (ret < 0)
+		return ret;
+	ctrl_dev->tx_ctrl_done = 0;
+
+	if (!atomic_read(&ccid_dev->online)) {
+		pr_debug("%s: USB cable not connected\n", __func__);
+		return -ENODEV;
+	}
+	ret = copy_to_user(buf, ctrl_dev->buf, count);
+	if (ret)
+		return -EFAULT;
+
+	return count;
+}
+
+static long
+ccid_ctrl_ioctl(struct file *fp, unsigned cmd, u_long arg)
+{
+	struct f_ccid *ccid_dev = fp->private_data;
+	struct usb_request              *req = ccid_dev->notify_req;
+	struct usb_ccid_notification     *ccid_notify = req->buf;
+	void __user *argp = (void __user *)arg;
+	int ret = 0;
+
+	switch (cmd) {
+	case CCID_NOTIFY_CARD:
+		if (copy_from_user(ccid_notify, argp,
+				sizeof(struct usb_ccid_notification)))
+			return -EFAULT;
+		req->length = 2;
+		break;
+	case CCID_NOTIFY_HWERROR:
+		if (copy_from_user(ccid_notify, argp,
+				sizeof(struct usb_ccid_notification)))
+			return -EFAULT;
+		req->length = 4;
+		break;
+	case CCID_READ_DTR:
+		if (copy_to_user((int *)arg, &ccid_dev->dtr_state, sizeof(int)))
+			return -EFAULT;
+		return 0;
+	}
+	ret = usb_ep_queue(ccid_dev->notify, ccid_dev->notify_req, GFP_KERNEL);
+	if (ret < 0) {
+		pr_err("ccid notify ep enqueue error %d\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
+static const struct file_operations ccid_ctrl_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ccid_ctrl_open,
+	.release	= ccid_ctrl_release,
+	.read		= ccid_ctrl_read,
+	.unlocked_ioctl	= ccid_ctrl_ioctl,
+};
+
+static struct miscdevice ccid_ctrl_device = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "ccid_ctrl",
+	.fops = &ccid_ctrl_fops,
+};
+
+static int ccid_ctrl_device_init(struct f_ccid *dev)
+{
+	int ret;
+	struct ccid_ctrl_dev *ctrl_dev = &dev->ctrl_dev;
+
+	INIT_LIST_HEAD(&ctrl_dev->tx_q);
+	init_waitqueue_head(&ctrl_dev->tx_wait_q);
+
+	ret = misc_register(&ccid_ctrl_device);
+	if (ret) {
+		pr_err("%s: failed to register misc device\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ccid_bind_config(struct usb_configuration *c)
+{
+	struct f_ccid *ccid_dev = _ccid_dev;
+
+	pr_debug("ccid_bind_config\n");
+	ccid_dev->cdev = c->cdev;
+	ccid_dev->function.name = FUNCTION_NAME;
+	ccid_dev->function.descriptors = ccid_fs_descs;
+	ccid_dev->function.hs_descriptors = ccid_hs_descs;
+	ccid_dev->function.bind = ccid_function_bind;
+	ccid_dev->function.unbind = ccid_function_unbind;
+	ccid_dev->function.set_alt = ccid_function_set_alt;
+	ccid_dev->function.setup = ccid_function_setup;
+	ccid_dev->function.disable = ccid_function_disable;
+
+	return usb_add_function(c, &ccid_dev->function);
+
+}
+
+static int ccid_setup(void)
+{
+	struct f_ccid  *ccid_dev;
+	int ret;
+
+	ccid_dev = kzalloc(sizeof(*ccid_dev), GFP_KERNEL);
+	if (!ccid_dev)
+		return -ENOMEM;
+
+	_ccid_dev = ccid_dev;
+	spin_lock_init(&ccid_dev->lock);
+
+	ret = ccid_ctrl_device_init(ccid_dev);
+	if (ret) {
+		pr_err("%s: ccid_ctrl_device_init failed, err:%d\n",
+				__func__, ret);
+		goto err_ctrl_init;
+	}
+	ret = ccid_bulk_device_init(ccid_dev);
+	if (ret) {
+		pr_err("%s: ccid_bulk_device_init failed, err:%d\n",
+				__func__, ret);
+		goto err_bulk_init;
+	}
+
+	return 0;
+err_bulk_init:
+	misc_deregister(&ccid_ctrl_device);
+err_ctrl_init:
+	kfree(ccid_dev);
+	pr_err("ccid gadget driver failed to initialize\n");
+	return ret;
+}
+
+static void ccid_cleanup(void)
+{
+	misc_deregister(&ccid_bulk_device);
+	misc_deregister(&ccid_ctrl_device);
+	kfree(_ccid_dev);
+}
diff --git a/drivers/usb/gadget/f_ccid.h b/drivers/usb/gadget/f_ccid.h
new file mode 100644
index 0000000..4d6a0ea
--- /dev/null
+++ b/drivers/usb/gadget/f_ccid.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011, 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 __F_CCID_H
+#define __F_CCID_H
+
+#define PROTOCOL_TO 0x01
+#define PROTOCOL_T1 0x02
+#define ABDATA_SIZE 512
+
+/* define for dwFeatures for Smart Card Device Class Descriptors */
+/* No special characteristics */
+#define CCID_FEATURES_NADA       0x00000000
+/* Automatic parameter configuration based on ATR data */
+#define CCID_FEATURES_AUTO_PCONF 0x00000002
+/* Automatic activation of ICC on inserting */
+#define CCID_FEATURES_AUTO_ACTIV 0x00000004
+/* Automatic ICC voltage selection */
+#define CCID_FEATURES_AUTO_VOLT  0x00000008
+/* Automatic ICC clock frequency change */
+#define CCID_FEATURES_AUTO_CLOCK 0x00000010
+/* Automatic baud rate change */
+#define CCID_FEATURES_AUTO_BAUD  0x00000020
+/*Automatic parameters negotiation made by the CCID */
+#define CCID_FEATURES_AUTO_PNEGO 0x00000040
+/* Automatic PPS made by the CCID according to the active parameters */
+#define CCID_FEATURES_AUTO_PPS   0x00000080
+/* CCID can set ICC in clock stop mode */
+#define CCID_FEATURES_ICCSTOP    0x00000100
+/* NAD value other than 00 accepted (T=1 protocol in use) */
+#define CCID_FEATURES_NAD        0x00000200
+/* Automatic IFSD exchange as first exchange (T=1 protocol in use) */
+#define CCID_FEATURES_AUTO_IFSD  0x00000400
+/* TPDU level exchanges with CCID */
+#define CCID_FEATURES_EXC_TPDU   0x00010000
+/* Short APDU level exchange with CCID */
+#define CCID_FEATURES_EXC_SAPDU  0x00020000
+/* Short and Extended APDU level exchange with CCID */
+#define CCID_FEATURES_EXC_APDU   0x00040000
+/* USB Wake up signaling supported on card insertion and removal */
+#define CCID_FEATURES_WAKEUP     0x00100000
+
+#define CCID_NOTIFY_CARD	_IOW('C', 1, struct usb_ccid_notification)
+#define CCID_NOTIFY_HWERROR	_IOW('C', 2, struct usb_ccid_notification)
+#define CCID_READ_DTR		_IOR('C', 3, int)
+
+struct usb_ccid_notification {
+	unsigned char buf[4];
+} __packed;
+
+struct ccid_bulk_in_header {
+	unsigned char bMessageType;
+	unsigned long wLength;
+	unsigned char bSlot;
+	unsigned char bSeq;
+	unsigned char bStatus;
+	unsigned char bError;
+	unsigned char bSpecific;
+	unsigned char abData[ABDATA_SIZE];
+	unsigned char bSizeToSend;
+} __packed;
+
+struct ccid_bulk_out_header {
+	unsigned char bMessageType;
+	unsigned long wLength;
+	unsigned char bSlot;
+	unsigned char bSeq;
+	unsigned char bSpecific_0;
+	unsigned char bSpecific_1;
+	unsigned char bSpecific_2;
+	unsigned char APDU[ABDATA_SIZE];
+} __packed;
+#endif
diff --git a/drivers/usb/misc/mdm_ctrl_bridge.c b/drivers/usb/misc/mdm_ctrl_bridge.c
index 87adf2e..0397428 100644
--- a/drivers/usb/misc/mdm_ctrl_bridge.c
+++ b/drivers/usb/misc/mdm_ctrl_bridge.c
@@ -318,7 +318,7 @@
 		return;
 
 	dev  = __dev[id];
-	if (!dev && !dev->brdg)
+	if (!dev || !dev->brdg)
 		return;
 
 	dev_dbg(&dev->udev->dev, "%s:\n", __func__);
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index c41fcfb..7c44a9a 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -120,7 +120,7 @@
 		return -EINVAL;
 
 	dev = __dev[id];
-	if (!dev && !dev->brdg)
+	if (!dev || !dev->brdg)
 		return -ENODEV;
 
 	dev->rx_unthrottled_cnt++;
@@ -321,7 +321,7 @@
 		return;
 
 	dev  = __dev[id];
-	if (!dev && !dev->brdg)
+	if (!dev || !dev->brdg)
 		return;
 
 	dev_dbg(&dev->udev->dev, "%s:\n", __func__);
@@ -872,7 +872,9 @@
 }
 
 static const struct usb_device_id bridge_ids[] = {
-	  { USB_DEVICE(0x5c6, 0x9001) },
+	{ USB_DEVICE(0x5c6, 0x9001) },
+
+	{ } /* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, bridge_ids);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index f8b320f..ec922f1 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -39,6 +39,7 @@
 #include <linux/mfd/pm8xxx/pm8921-charger.h>
 
 #include <mach/clk.h>
+#include <mach/msm_xo.h>
 
 #define MSM_USB_BASE	(motg->regs)
 #define DRIVER_NAME	"msm_otg"
@@ -506,14 +507,15 @@
 		return ret;
 	}
 
-	ulpi_init(motg);
-
 	ret = msm_otg_link_reset(motg);
 	if (ret) {
 		dev_err(otg->dev, "link reset failed\n");
 		return ret;
 	}
 	msleep(100);
+
+	ulpi_init(motg);
+
 	/* Ensure that RESET operation is completed before turning off clock */
 	mb();
 
@@ -568,6 +570,7 @@
 	int cnt = 0;
 	bool session_active;
 	u32 phy_ctrl_val = 0;
+	unsigned ret;
 
 	if (atomic_read(&motg->in_lpm))
 		return 0;
@@ -661,6 +664,12 @@
 	if (!IS_ERR(motg->pclk_src))
 		clk_disable(motg->pclk_src);
 
+	/* usb phy no more require TCXO clock, hence vote for TCXO disable */
+	ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
+	if (ret)
+		dev_err(otg->dev, "%s failed to devote for "
+			"TCXO D0 buffer%d\n", __func__, ret);
+
 	if (motg->caps & ALLOW_PHY_POWER_COLLAPSE && !session_active) {
 		msm_hsusb_ldo_enable(motg, 0);
 		motg->lpm_flags |= PHY_PWR_COLLAPSED;
@@ -695,11 +704,19 @@
 	int cnt = 0;
 	unsigned temp;
 	u32 phy_ctrl_val = 0;
+	unsigned ret;
 
 	if (!atomic_read(&motg->in_lpm))
 		return 0;
 
 	wake_lock(&motg->wlock);
+
+	/* Vote for TCXO when waking up the phy */
+	ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
+	if (ret)
+		dev_err(otg->dev, "%s failed to vote for "
+			"TCXO D0 buffer%d\n", __func__, ret);
+
 	if (!IS_ERR(motg->pclk_src))
 		clk_enable(motg->pclk_src);
 
@@ -2282,12 +2299,27 @@
 		goto free_regs;
 	}
 
+	motg->xo_handle = msm_xo_get(MSM_XO_TCXO_D0, "usb");
+	if (IS_ERR(motg->xo_handle)) {
+		dev_err(&pdev->dev, "%s not able to get the handle "
+			"to vote for TCXO D0 buffer\n", __func__);
+		ret = PTR_ERR(motg->xo_handle);
+		goto free_regs;
+	}
+
+	ret = msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_ON);
+	if (ret) {
+		dev_err(&pdev->dev, "%s failed to vote for TCXO "
+			"D0 buffer%d\n", __func__, ret);
+		goto free_xo_handle;
+	}
+
 	clk_enable(motg->pclk);
 
 	ret = msm_hsusb_init_vddcx(motg, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "hsusb vddcx init failed\n");
-		goto free_regs;
+		goto devote_xo_handle;
 	}
 
 	ret = msm_hsusb_config_vddcx(1);
@@ -2403,6 +2435,10 @@
 	msm_hsusb_ldo_init(motg, 0);
 free_init_vddcx:
 	msm_hsusb_init_vddcx(motg, 0);
+devote_xo_handle:
+	msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
+free_xo_handle:
+	msm_xo_put(motg->xo_handle);
 free_regs:
 	iounmap(motg->regs);
 put_core_clk:
@@ -2482,6 +2518,7 @@
 		clk_disable(motg->pclk_src);
 		clk_put(motg->pclk_src);
 	}
+	msm_xo_put(motg->xo_handle);
 	msm_hsusb_ldo_enable(motg, 0);
 	msm_hsusb_ldo_init(motg, 0);
 	msm_hsusb_init_vddcx(motg, 0);
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index f7bf993..35d1714 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -295,11 +295,11 @@
 	select FB_MSM_MIPI_DSI_SIMULATOR
 	default n
 
-config FB_MSM_OVERLAY_WRITEBACK
+config FB_MSM_OVERLAY0_WRITEBACK
 	depends on FB_MSM_OVERLAY
-        bool "MDP overlay write back mode enable"
+        bool "MDP overlay0 write back mode enable"
 	---help---
-	  Support for MDP4 OVERLAY write back mode
+	  Support for MDP4 OVERLAY0 write back mode
 
 config FB_MSM_WRITEBACK_MSM_PANEL
 	depends on FB_MSM_OVERLAY
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 8a1d56e..0f1d19b 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -51,6 +51,12 @@
 
 static int msm_hdmi_sample_rate = MSM_HDMI_SAMPLE_RATE_48KHZ;
 
+/* HDMI/HDCP Registers */
+#define HDCP_DDC_STATUS		0x0128
+#define HDCP_DDC_CTRL_0		0x0120
+#define HDCP_DDC_CTRL_1		0x0124
+#define HDMI_DDC_CTRL		0x020C
+
 struct workqueue_struct *hdmi_work_queue;
 struct hdmi_msm_state_type *hdmi_msm_state;
 
@@ -1072,6 +1078,8 @@
 		DEV_DBG("calling reauthenticate from %s HDCP FAIL INT ",
 		    __func__);
 
+		/* Clear AUTH_FAIL_INFO as well */
+		HDMI_OUTP(0x0118, (hdcp_int_val | (1 << 7)));
 		return IRQ_HANDLED;
 	}
 	/*    [8] DDC_XFER_REQ_INT	[R]	HDCP DDC Transfer Request
@@ -2156,8 +2164,109 @@
 
 	if (hdcp_link_status & 0x00000004)
 		hdcp_auth_info((hdcp_link_status & 0x000000F0) >> 4);
+
+	/* Disable HDCP interrupts */
+	HDMI_OUTP(0x0118, 0x0);
 }
 
+static void check_and_clear_HDCP_DDC_Failure(void)
+{
+	int hdcp_ddc_ctrl1_reg;
+	int hdcp_ddc_status;
+	int failure;
+	int nack0;
+
+	/*
+	 * Check for any DDC transfer failures
+	 * 0x0128 HDCP_DDC_STATUS
+	 * [16] FAILED		Indicates that the last HDCP HW DDC transer
+	 *			failed. This occurs when a transfer is
+	 *			attempted with HDCP DDC disabled
+	 *			(HDCP_DDC_DISABLE=1) or the number of retries
+	 *			match HDCP_DDC_RETRY_CNT
+	 *
+	 * [14] NACK0		Indicates that the last HDCP HW DDC transfer
+	 *			was aborted due to a NACK on the first
+	 *			transaction - cleared by writing 0 to GO bit
+	 */
+	hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+	failure = (hdcp_ddc_status >> 16) & 0x1;
+	nack0 = (hdcp_ddc_status >> 14) & 0x1;
+	DEV_DBG("%s: On Entry: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
+		"NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
+
+	if (failure == 0x1) {
+		/*
+		 * Indicates that the last HDCP HW DDC transfer failed.
+		 * This occurs when a transfer is attempted with HDCP DDC
+		 * disabled (HDCP_DDC_DISABLE=1) or the number of retries
+		 * matches HDCP_DDC_RETRY_CNT.
+		 * Failure occured,  let's clear it.
+		 */
+		DEV_INFO("%s: DDC failure detected. HDCP_DDC_STATUS=0x%08x\n",
+			 __func__, hdcp_ddc_status);
+		/*
+		 * First, Disable DDC
+		 * 0x0120 HDCP_DDC_CTRL_0
+		 * [0] DDC_DISABLE	Determines whether HDCP Ri and Pj reads
+		 *			are done unassisted by hardware or by
+		 *			software via HDMI_DDC (HDCP provides
+		 *			interrupts to request software
+		 *			transfers)
+		 *     0 : Use Hardware DDC
+		 *     1 : Use Software DDC
+		 */
+		HDMI_OUTP(HDCP_DDC_CTRL_0, 0x1);
+
+		/*
+		 * ACK the Failure to Clear it
+		 * 0x0124 HDCP_DDC_CTRL_1
+		 * [0] DDC_FAILED_ACK	Write 1 to clear
+		 *			HDCP_STATUS.HDCP_DDC_FAILED
+		 */
+		hdcp_ddc_ctrl1_reg = HDMI_INP(HDCP_DDC_CTRL_1);
+		HDMI_OUTP(HDCP_DDC_CTRL_1, hdcp_ddc_ctrl1_reg | 0x1);
+
+		/* Check if the FAILURE got Cleared */
+		hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+		hdcp_ddc_status = (hdcp_ddc_status >> 16) & 0x1;
+		if (hdcp_ddc_status == 0x0) {
+			DEV_INFO("%s: HDCP DDC Failure has been cleared\n",
+				  __func__);
+		} else {
+			DEV_WARN("%s: Error: HDCP DDC Failure DID NOT get"
+				 "cleared\n", __func__);
+		}
+
+		/* Re-Enable HDCP DDC */
+		HDMI_OUTP(HDCP_DDC_CTRL_0, 0x0);
+	}
+
+	if (nack0 == 0x1) {
+		/*
+		 * 0x020C HDMI_DDC_CTRL
+		 * [3] SW_STATUS_RESET	Write 1 to reset HDMI_DDC_SW_STATUS
+		 *			flags, will reset SW_DONE, ABORTED,
+		 *			TIMEOUT, SW_INTERRUPTED,
+		 *			BUFFER_OVERFLOW, STOPPED_ON_NACK, NACK0,
+		 *			NACK1, NACK2, NACK3
+		 */
+		HDMI_OUTP_ND(HDMI_DDC_CTRL,
+			     HDMI_INP(HDMI_DDC_CTRL) | (0x1 << 3));
+		msleep(20);
+		HDMI_OUTP_ND(HDMI_DDC_CTRL,
+			     HDMI_INP(HDMI_DDC_CTRL) & ~(0x1 << 3));
+	}
+
+	hdcp_ddc_status = HDMI_INP(HDCP_DDC_STATUS);
+
+	failure = (hdcp_ddc_status >> 16) & 0x1;
+	nack0 = (hdcp_ddc_status >> 14) & 0x1;
+	DEV_DBG("%s: On Exit: HDCP_DDC_STATUS = 0x%x, FAILURE = %d,"
+		"NACK0 = %d\n", __func__ , hdcp_ddc_status, failure, nack0);
+}
+
+
 static int hdcp_authentication_part1(void)
 {
 	int ret = 0;
@@ -2275,6 +2384,12 @@
 		/* encryption_enable | enable  */
 		HDMI_OUTP(0x0110, (1 << 8) | (1 << 0));
 
+		/*
+		 * Check to see if a HDCP DDC Failure is indicated in
+		 * HDCP_DDC_STATUS. If yes, clear it.
+		 */
+		check_and_clear_HDCP_DDC_Failure();
+
 		/* 0x0118 HDCP_INT_CTRL
 		 *    [2] AUTH_SUCCESS_MASK	[R/W]	Mask bit for\
 		 *					HDCP Authentication
@@ -2314,6 +2429,12 @@
 			goto error;
 		}
 
+		/*
+		 * A small delay is needed here to avoid device crash observed
+		 * during reauthentication in MSM8960
+		 */
+		msleep(20);
+
 		/* 0x0168 HDCP_RCVPORT_DATA12
 		   [23:8] BSTATUS
 		   [7:0] BCAPS */
@@ -4338,6 +4459,9 @@
 {
 	int rc;
 
+	if (cpu_is_msm8627())
+		return 0;
+
 	if (msm_fb_detect_client("hdmi_msm"))
 		return 0;
 
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index 9b9ee94..c6f9fb2 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -241,7 +241,8 @@
 #ifdef ENABLE_FWD_LINK_SKEW_CALIBRATION
 	if (mddi_client_type < 2) {
 		/* For skew calibration, clock should be less than 50MHz */
-		if (!clk_set_min_rate(mddi_clk, 49000000)) {
+		clk_rate = clk_round_rate(mddi_clk, 49000000);
+		if (!clk_set_rate(mddi_clk, clk_rate)) {
 			stat_reg = mddi_host_reg_in(STAT);
 			printk(KERN_DEBUG "\n stat_reg = 0x%x", stat_reg);
 			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE);
@@ -253,7 +254,7 @@
 			mddi_host_reg_out(CMD, MDDI_CMD_SEND_RTD);
 			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1);
 		} else {
-			printk(KERN_ERR "%s: clk_set_min_rate failed\n",
+			printk(KERN_ERR "%s: clk_set_rate failed\n",
 				__func__);
 		}
 	}
@@ -269,8 +270,9 @@
 			  "%s: can't select mddi io clk targate rate = %d\n",
 			  __func__, clk_rate);
 
-	if (clk_set_min_rate(mddi_clk, clk_rate) < 0)
-		printk(KERN_ERR "%s: clk_set_min_rate failed\n",
+	clk_rate = clk_round_rate(mddi_clk, clk_rate);
+	if (clk_set_rate(mddi_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_rate failed\n",
 			__func__);
 
 #ifdef CONFIG_MSM_BUS_SCALING
@@ -449,9 +451,6 @@
 	mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
 	mddi_host_reg_out(PAD_CTL, 0x0);
 
-	if (clk_set_min_rate(mddi_clk, 0) < 0)
-		printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
-
 	pmdh_clk_disable();
 
 	if (mddi_pdata && mddi_pdata->mddi_power_save)
@@ -477,9 +476,6 @@
 	mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
 	mddi_host_reg_out(PAD_CTL, 0x0);
 
-	if (clk_set_min_rate(mddi_clk, 0) < 0)
-		printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
-
 	pmdh_clk_disable();
 
 	return 0;
@@ -551,6 +547,7 @@
 static int __init mddi_driver_init(void)
 {
 	int ret;
+	unsigned long rate;
 	pmdh_clk_status = 0;
 
 	mddi_clk = clk_get(NULL, "mddi_clk");
@@ -558,9 +555,10 @@
 		printk(KERN_ERR "can't find mddi_clk\n");
 		return PTR_ERR(mddi_clk);
 	}
-	ret = clk_set_min_rate(mddi_clk, 49000000);
+	rate = clk_round_rate(mddi_clk, 49000000);
+	ret = clk_set_rate(mddi_clk, rate);
 	if (ret)
-		printk(KERN_ERR "Can't set mddi_clk min rate to 49000000\n");
+		printk(KERN_ERR "Can't set mddi_clk min rate to %lu\n", rate);
 
 	printk(KERN_INFO "mddi_clk init rate is %lu\n",
 		clk_get_rate(mddi_clk));
diff --git a/drivers/video/msm/mddi_ext.c b/drivers/video/msm/mddi_ext.c
index 0ecd593..677b46c 100644
--- a/drivers/video/msm/mddi_ext.c
+++ b/drivers/video/msm/mddi_ext.c
@@ -126,8 +126,9 @@
 			  "%s: can't select mddi io clk targate rate = %d\n",
 			  __func__, clk_rate);
 
-	if (clk_set_min_rate(mddi_ext_clk, clk_rate) < 0)
-		printk(KERN_ERR "%s: clk_set_min_rate failed\n",
+	clk_rate = clk_round_rate(mddi_ext_clk, clk_rate);
+	if (clk_set_rate(mddi_ext_clk, clk_rate) < 0)
+		printk(KERN_ERR "%s: clk_set_rate failed\n",
 			__func__);
 
 	mddi_host_start_ext_display();
@@ -265,9 +266,6 @@
 
 	mddi_ext_is_in_suspend = 1;
 
-	if (clk_set_min_rate(mddi_ext_clk, 0) < 0)
-		printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
-
 	clk_disable(mddi_ext_clk);
 	if (mddi_ext_pclk)
 		clk_disable(mddi_ext_pclk);
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index aeeb503..989b154 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -57,7 +57,7 @@
 struct semaphore mdp_ppp_mutex;
 struct semaphore mdp_pipe_ctrl_mutex;
 
-unsigned long mdp_timer_duration = (HZ/20);   /* 50 msecond */
+unsigned long mdp_timer_duration = (HZ/50); /* 20 ms */
 
 boolean mdp_ppp_waiting = FALSE;
 uint32 mdp_tv_underflow_cnt;
@@ -1106,11 +1106,10 @@
 {
 	uint8 count;
 	uint32 current_rate;
-	if (mdp_clk && mdp_pdata
-		&& mdp_pdata->mdp_core_clk_table) {
-		if (clk_set_min_rate(mdp_clk,
-				 min_clk_rate) < 0)
-			printk(KERN_ERR "%s: clk_set_min_rate failed\n",
+	if (mdp_clk && mdp_pdata && mdp_pdata->mdp_core_clk_table) {
+		min_clk_rate = clk_round_rate(mdp_clk, min_clk_rate);
+		if (clk_set_rate(mdp_clk, min_clk_rate) < 0)
+			printk(KERN_ERR "%s: clk_set_rate failed\n",
 							 __func__);
 		else {
 			count = 0;
@@ -1340,6 +1339,10 @@
 
 	/* link to the latest pdev */
 	mfd->pdev = msm_fb_dev;
+	mfd->mdp_rev = mdp_rev;
+
+	mfd->ov0_blt_state  = 0;
+	mfd->use_ov0_blt = 0 ;
 
 	/* add panel data */
 	if (platform_device_add_data
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 383a16d..84beb6a 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1555,8 +1555,8 @@
 	pr_debug("fillratex100 %lu, mdp_pixels_produced %lu\n",
 		fillratex100, mdp_pixels_produced);
 	if (mdp_pixels_produced <= mfd->panel_info.xres) {
-		pr_err("%s(): LCDC underflow detected during downscale\n",
-			__func__);
+		pr_err("%s():display underflow detected with downscale"
+			" params\n", __func__);
 		return -ERANGE;
 	}
 
@@ -1833,7 +1833,6 @@
 }
 #endif
 
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
 int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -1876,7 +1875,6 @@
 
 	return ret;
 }
-#endif
 
 int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
 {
@@ -1968,6 +1966,60 @@
 	}
 }
 
+static void mdp4_overlay_update_blt_mode(struct msm_fb_data_type *mfd)
+{
+	if (mfd->use_ov0_blt) {
+		if (mfd->panel_info.type == LCDC_PANEL)
+			mdp4_lcdc_overlay_blt_start(mfd);
+		else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+			mdp4_dsi_video_blt_start(mfd);
+		else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+			mdp4_dsi_overlay_blt_start(mfd);
+	} else {
+		if (mfd->panel_info.type == LCDC_PANEL)
+			mdp4_lcdc_overlay_blt_stop(mfd);
+		else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+			mdp4_dsi_video_blt_stop(mfd);
+		else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+			mdp4_dsi_overlay_blt_stop(mfd);
+	}
+}
+
+static u32 mdp4_overlay_blt_enable(struct mdp_overlay *req,
+	struct msm_fb_data_type *mfd, uint32 perf_level)
+{
+	u32 clk_rate = mfd->panel_info.clk_rate;
+	u32 pull_mode = 0, use_blt = 0;
+
+	if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+		clk_rate = (&mfd->panel_info.mipi)->dsi_pclk_rate;
+
+	if ((mfd->panel_info.type == LCDC_PANEL) ||
+		(mfd->panel_info.type == MIPI_VIDEO_PANEL))
+		pull_mode = 1;
+
+	if (pull_mode && (req->src_rect.h > req->dst_rect.h ||
+		req->src_rect.w > req->dst_rect.w)) {
+		if (mdp4_overlay_validate_downscale(req, mfd, perf_level,
+			clk_rate))
+			use_blt = 1;
+	}
+
+	if (mfd->mdp_rev == MDP_REV_41) {
+		/*
+		* writeback (blt) mode to provide work around for
+		* dsi cmd mode interface hardware bug.
+		*/
+		if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+			if (req->dst_rect.x != 0)
+				use_blt = 1;
+		}
+		if (mfd->panel_info.xres > 1280)
+			use_blt = 1;
+	}
+	return use_blt;
+}
+
 int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
@@ -1992,22 +2044,6 @@
 
 	perf_level = mdp4_overlay_get_perf_level(req);
 
-	if ((mfd->panel_info.type == LCDC_PANEL) &&
-	    (req->src_rect.h >
-		req->dst_rect.h || req->src_rect.w > req->dst_rect.w)) {
-		if (mdp4_overlay_validate_downscale(req, mfd,
-			perf_level, mfd->panel_info.clk_rate))
-				mdp4_lcdc_overlay_blt_start(mfd);
-	}
-
-	if ((mfd->panel_info.type == MIPI_VIDEO_PANEL) &&
-	    (req->src_rect.h >
-		req->dst_rect.h || req->src_rect.w > req->dst_rect.w)) {
-		if (mdp4_overlay_validate_downscale(req, mfd,
-			perf_level, (&mfd->panel_info.mipi)->dsi_pclk_rate))
-				mdp4_dsi_video_blt_start(mfd);
-	}
-
 	mixer = mfd->panel_info.pdest;	/* DISPLAY_1 or DISPLAY_2 */
 
 	ret = mdp4_overlay_req2pipe(req, mixer, &pipe, mfd);
@@ -2017,15 +2053,10 @@
 		return ret;
 	}
 
-	/*
-	 * writeback (blt) mode to provide work around for
-	 * dsi cmd mode interface hardware bug.
-	 */
-	if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
-		if (mixer == MDP4_MIXER0 && req->dst_rect.x != 0) {
-			mdp4_dsi_blt_dmap_busy_wait(mfd);
-			mdp4_dsi_overlay_blt_start(mfd);
-		}
+	if (mixer == MDP4_MIXER0) {
+		u32 use_blt = mdp4_overlay_blt_enable(req, mfd,	perf_level);
+		mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
+		mfd->use_ov0_blt |= (use_blt << (pipe->pipe_ndx-1));
 	}
 
 	/* return id back to user */
@@ -2136,11 +2167,11 @@
 	mdp4_mixer_stage_down(pipe);
 
 	if (pipe->mixer_num == MDP4_MIXER0) {
+
 #ifdef CONFIG_FB_MSM_MIPI_DSI
 		if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
 			if (mfd->panel_power_on)
-				if (mdp4_dsi_overlay_blt_stop(mfd) == 0)
-					mdp4_dsi_cmd_overlay_restore();
+				mdp4_dsi_cmd_overlay_restore();
 		}  else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
 			mdp4_overlay_reg_flush(pipe, 1);
 			if (mfd->panel_power_on) {
@@ -2149,7 +2180,6 @@
 				mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
 				pipe->flags = flags;
 			}
-			mdp4_dsi_video_blt_stop(mfd);
 		}
 #else
 		if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
@@ -2168,8 +2198,12 @@
 				mdp4_overlay_lcdc_vsync_push(mfd, pipe);
 				pipe->flags = flags;
 			}
-			mdp4_lcdc_overlay_blt_stop(mfd);
 		}
+
+		mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
+		mdp4_overlay_update_blt_mode(mfd);
+		mfd->ov0_blt_state = mfd->use_ov0_blt;
+
 	}
 #ifdef CONFIG_FB_MSM_DTV
 	else {	/* mixer1, DTV, ATV */
@@ -2402,6 +2436,11 @@
 		}
 	}
 
+	if (mfd->use_ov0_blt != mfd->ov0_blt_state) {
+		mdp4_overlay_update_blt_mode(mfd);
+		mfd->ov0_blt_state = mfd->use_ov0_blt;
+	}
+
 	if (pipe->pipe_num >= OVERLAY_PIPE_VG1)
 		mdp4_overlay_vg_setup(pipe);	/* video/graphic pipe */
 	else {
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index aecf554..d76e252 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -302,8 +302,6 @@
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
-
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
 int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd)
 {
 	unsigned long flag;
@@ -370,21 +368,6 @@
 		mdp4_dsi_overlay_blt_stop(mfd);
 
 }
-#else
-int mdp4_dsi_overlay_blt_offset(struct msm_fb_data_type *mfd,
-					struct msmfb_overlay_blt *req)
-{
-	return 0;
-}
-int mdp4_dsi_overlay_blt_start(struct msm_fb_data_type *mfd)
-{
-	return -EBUSY;
-}
-int mdp4_dsi_overlay_blt_stop(struct msm_fb_data_type *mfd)
-{
-	return -EBUSY;
-}
-#endif
 
 void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe)
 {
@@ -447,7 +430,6 @@
 			mdp_intr_mask &= ~INTR_DMA_P_DONE;
 			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
 		}
-		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
 		mdp_disable_irq_nosync(MDP_DMA2_TERM);  /* disable intr */
 		return;
 	}
@@ -467,8 +449,6 @@
 	mdp4_stat.kickoff_dmap++;
 	/* trigger dsi cmd engine */
 	mipi_dsi_cmd_mdp_start();
-
-	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
 }
 
 
@@ -480,7 +460,6 @@
 	int diff;
 
 	if (dsi_pipe->blt_addr == 0) {
-		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
 		spin_lock(&mdp_spin_lock);
 		dma->busy = FALSE;
 		spin_unlock(&mdp_spin_lock);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 63beb88..938d7c6 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -479,30 +479,6 @@
 	mdp4_set_perf_level();
 }
 
-static void mdp4_overlay_dsi_video_prefill(struct msm_fb_data_type *mfd)
-{
-	unsigned long flag;
-
-	if (dsi_pipe->blt_addr) {
-		mdp4_overlay_dsi_video_dma_busy_wait(mfd);
-
-		mdp4_dsi_video_blt_ov_update(dsi_pipe);
-		dsi_pipe->ov_cnt++;
-
-		spin_lock_irqsave(&mdp_spin_lock, flag);
-		outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
-		mdp_intr_mask |= INTR_OVERLAY0_DONE;
-		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
-		mdp_enable_irq(MDP_OVERLAY0_TERM);
-		mfd->dma->busy = TRUE;
-		mb();	/* make sure all registers updated */
-		spin_unlock_irqrestore(&mdp_spin_lock, flag);
-		outpdw(MDP_BASE + 0x0004, 0); /* kickoff overlay engine */
-		mdp4_stat.kickoff_ov0++;
-		mb();
-	}
-}
-
 void mdp4_overlay_dsi_video_vsync_push(struct msm_fb_data_type *mfd,
 			struct mdp4_overlay_pipe *pipe)
 {
@@ -569,7 +545,30 @@
 	complete(&dma->comp);
 }
 
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
+static void mdp4_overlay_dsi_video_prefill(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	if (dsi_pipe->blt_addr) {
+		mdp4_overlay_dsi_video_dma_busy_wait(mfd);
+
+		mdp4_dsi_video_blt_ov_update(dsi_pipe);
+		dsi_pipe->ov_cnt++;
+
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		mdp_enable_irq(MDP_OVERLAY0_TERM);
+		mfd->dma->busy = TRUE;
+		mb();	/* make sure all registers updated */
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		outpdw(MDP_BASE + 0x0004, 0); /* kickoff overlay engine */
+		mdp4_stat.kickoff_ov0++;
+		mb();
+	}
+}
+
 /*
  * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
  * has enough space h * w * 3 * 2
@@ -658,24 +657,6 @@
 {
 	mdp4_dsi_video_do_blt(mfd, 0);
 }
-#else
-int mdp4_dsi_video_overlay_blt_offset(struct msm_fb_data_type *mfd,
-					struct msmfb_overlay_blt *req)
-{
-	return 0;
-}
-void mdp4_dsi_video_overlay_blt(struct msm_fb_data_type *mfd,
-					struct msmfb_overlay_blt *req)
-{
-	return;
-}
-void mdp4_dsi_video_blt_start(struct msm_fb_data_type *mfd)
-{
-}
-void mdp4_dsi_video_blt_stop(struct msm_fb_data_type *mfd)
-{
-}
-#endif
 
 void mdp4_dsi_video_overlay(struct msm_fb_data_type *mfd)
 {
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a8e39d0..f318691 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -464,7 +464,6 @@
 	complete(&dma->comp);
 }
 
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
 /*
  * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
  * has enough space h * w * 3 * 2
@@ -531,24 +530,6 @@
 {
 	mdp4_lcdc_do_blt(mfd, 0);
 }
-#else
-int mdp4_lcdc_overlay_blt_offset(struct msm_fb_data_type *mfd,
-					struct msmfb_overlay_blt *req)
-{
-	return 0;
-}
-void mdp4_lcdc_overlay_blt(struct msm_fb_data_type *mfd,
-					struct msmfb_overlay_blt *req)
-{
-	return;
-}
-void mdp4_lcdc_overlay_blt_start(struct msm_fb_data_type *mfd)
-{
-}
-void mdp4_lcdc_overlay_blt_stop(struct msm_fb_data_type *mfd)
-{
-}
-#endif
 
 void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd)
 {
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index f2e2f10..a177976 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1202,7 +1202,7 @@
 	if (mfd->panel_info.mipi.no_max_pkt_size) {
 		/* Only support rlen = 4*n */
 		rlen += 3;
-		rlen &= 0x03;
+		rlen &= ~0x03;
 	}
 
 	len = rlen;
@@ -1491,6 +1491,7 @@
 
 	if (isr & DSI_INTR_CMD_MDP_DONE) {
 		mipi_dsi_mdp_stat_inc(STAT_DSI_MDP);
+		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, TRUE);
 		spin_lock(&dsi_mdp_lock);
 		dsi_mdp_busy = FALSE;
 		spin_unlock(&dsi_mdp_lock);
diff --git a/drivers/video/msm/mipi_tc358764_dsi2lvds.c b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
index 2594c1d..8055bd0 100644
--- a/drivers/video/msm/mipi_tc358764_dsi2lvds.c
+++ b/drivers/video/msm/mipi_tc358764_dsi2lvds.c
@@ -236,10 +236,9 @@
 	mipi_dsi_buf_init(&d2l_tx_buf);
 	mipi_dsi_buf_init(&d2l_rx_buf);
 
-	mutex_lock(&mfd->dma->ov_mutex);
+	/* mutex had been acquried at dsi_on */
 	len = mipi_dsi_cmds_rx(mfd, &d2l_tx_buf, &d2l_rx_buf,
 			       &cmd_read_reg, len);
-	mutex_unlock(&mfd->dma->ov_mutex);
 
 	data = *(u32 *)d2l_rx_buf.data;
 
@@ -269,9 +268,8 @@
 	payload.addr = reg;
 	payload.data = data;
 
-	mutex_lock(&mfd->dma->ov_mutex);
+	/* mutex had been acquried at dsi_on */
 	mipi_dsi_cmds_tx(mfd, &d2l_tx_buf, &cmd_write_reg, 1);
-	mutex_unlock(&mfd->dma->ov_mutex);
 
 	pr_debug("%s: reg=0x%x. data=0x%x.\n", __func__, reg, data);
 
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 10e4156..59c2afe 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2569,8 +2569,6 @@
 	return 0;
 }
 
-
-#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
 static int msmfb_overlay_blt(struct fb_info *info, unsigned long *argp)
 {
 	int     ret;
@@ -2607,16 +2605,6 @@
 
 	return ret;
 }
-#else
-static int msmfb_overlay_blt(struct fb_info *info, unsigned long *argp)
-{
-	return 0;
-}
-static int msmfb_overlay_blt_off(struct fb_info *info, unsigned long *argp)
-{
-	return 0;
-}
-#endif
 
 #ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
 static int msmfb_overlay_ioctl_writeback_init(struct fb_info *info)
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index bc25062..de2734d 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -166,7 +166,6 @@
 	struct completion msmfb_update_notify;
 	struct completion msmfb_no_update_notify;
 	u32 ov_start, ov_end;
-
 	struct mutex writeback_mutex;
 	struct mutex unregister_mutex;
 	struct list_head writeback_busy_queue;
@@ -174,6 +173,8 @@
 	struct list_head writeback_register_queue;
 	wait_queue_head_t		wait_q;
 	struct ion_client *client;
+	u32 mdp_rev;
+	u32 use_ov0_blt, ov0_blt_state;
 };
 
 struct dentry *msm_fb_get_debugfs_root(void);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
index 8b293b6..cf8f712 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c
@@ -242,7 +242,11 @@
 		decoder->hw_bufs.desc),
 	seq_start_param.descriptor_buffer_size =
 		decoder->hw_bufs.desc.buffer_size;
-	if (decoder->codec.codec == VCD_CODEC_MPEG4)
+	if ((decoder->codec.codec == VCD_CODEC_MPEG4) ||
+		(decoder->codec.codec == VCD_CODEC_DIVX_4) ||
+		(decoder->codec.codec == VCD_CODEC_DIVX_5) ||
+		(decoder->codec.codec == VCD_CODEC_DIVX_6) ||
+		(decoder->codec.codec == VCD_CODEC_XVID))
 		vidc_sm_set_mpeg4_profile_override(
 			&ddl->shared_mem[ddl->command_channel],
 			VIDC_SM_PROFILE_INFO_ASP);
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 3924088..75e0acf 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -1900,7 +1900,8 @@
 		VCD_MSG_HIGH("Got input done for EOS initiator");
 		transc->input_done = false;
 		transc->in_use = true;
-		if (codec_config ||
+		if ((codec_config &&
+			 (status != VCD_ERR_BITSTREAM_ERR)) ||
 			((status == VCD_ERR_BITSTREAM_ERR) &&
 			 !(cctxt->status.mask & VCD_FIRST_IP_DONE) &&
 			 (core_type == VCD_CORE_720P)))
diff --git a/fs/yaffs2/yaffs_vfs.c b/fs/yaffs2/yaffs_vfs.c
index a4db5cc..f56e12c 100644
--- a/fs/yaffs2/yaffs_vfs.c
+++ b/fs/yaffs2/yaffs_vfs.c
@@ -65,7 +65,7 @@
 
 #define YPROC_ROOT  NULL
 
-#define Y_INIT_TIMER(a)	init_timer_on_stack(a)
+#define Y_INIT_TIMER(a, b, c)	setup_deferrable_timer_on_stack(a, b, c)
 
 #define WRITE_SIZE_STR "writesize"
 #define WRITE_SIZE(mtd) ((mtd)->writesize)
@@ -1674,10 +1674,9 @@
 		if (time_before(expires, now))
 			expires = now + HZ;
 
-		Y_INIT_TIMER(&timer);
+		Y_INIT_TIMER(&timer, yaffs_background_waker,
+				(unsigned long)current);
 		timer.expires = expires + 1;
-		timer.data = (unsigned long)current;
-		timer.function = yaffs_background_waker;
 
 		set_current_state(TASK_INTERRUPTIBLE);
 		add_timer(&timer);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1d37f42..7213b52 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -11,6 +11,8 @@
 #ifndef __LINUX_CLK_H
 #define __LINUX_CLK_H
 
+#include <linux/kernel.h>
+
 struct device;
 
 /*
@@ -41,11 +43,31 @@
 struct clk *clk_get(struct device *dev, const char *id);
 
 /**
+ * clk_prepare - prepare a clock source
+ * @clk: clock source
+ *
+ * This prepares the clock source for use.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+int clk_prepare(struct clk *clk);
+#else
+static inline int clk_prepare(struct clk *clk)
+{
+	might_sleep();
+	return 0;
+}
+#endif
+
+/**
  * clk_enable - inform the system when the clock source should be running.
  * @clk: clock source
  *
  * If the clock can not be enabled/disabled, this should return success.
  *
+ * May be called from atomic contexts.
+ *
  * Returns success (0) or negative errno.
  */
 int clk_enable(struct clk *clk);
@@ -57,6 +79,8 @@
  * Inform the system that a clock source is no longer required by
  * a driver and may be shut down.
  *
+ * May be called from atomic contexts.
+ *
  * Implementation detail: if the clock source is shared between
  * multiple drivers, clk_enable() calls must be balanced by the
  * same number of clk_disable() calls for the clock source to be
@@ -64,6 +88,25 @@
  */
 void clk_disable(struct clk *clk);
 
+
+/**
+ * clk_unprepare - undo preparation of a clock source
+ * @clk: clock source
+ *
+ * This undoes a previously prepared clock.  The caller must balance
+ * the number of prepare and unprepare calls.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+void clk_unprepare(struct clk *clk);
+#else
+static inline void clk_unprepare(struct clk *clk)
+{
+	might_sleep();
+}
+#endif
+
 /**
  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
  *		  This is only valid once the clock source has been enabled.
diff --git a/include/linux/cpu_pm.h b/include/linux/cpu_pm.h
index a165fd7..d399bf8 100644
--- a/include/linux/cpu_pm.h
+++ b/include/linux/cpu_pm.h
@@ -67,7 +67,13 @@
 	CPU_CLUSTER_PM_EXIT,
 };
 
+#ifdef CONFIG_CPU_PM
 int cpu_pm_register_notifier(struct notifier_block *nb);
+#else
+static inline int cpu_pm_register_notifier(struct notifier_block *nb)
+{ return 0; }
+#endif
+
 int cpu_pm_unregister_notifier(struct notifier_block *nb);
 
 /*
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index bf56b6f..1c4085e 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1305,6 +1305,7 @@
 	WLAN_KEY_LEN_CCMP = 16,
 	WLAN_KEY_LEN_TKIP = 32,
 	WLAN_KEY_LEN_AES_CMAC = 16,
+	WLAN_KEY_LEN_WAPI_SMS4 = 32,
 };
 
 /**
@@ -1434,6 +1435,7 @@
 #define WLAN_CIPHER_SUITE_CCMP		0x000FAC04
 #define WLAN_CIPHER_SUITE_WEP104	0x000FAC05
 #define WLAN_CIPHER_SUITE_AES_CMAC	0x000FAC06
+#define WLAN_CIPHER_SUITE_SMS4		0x00147201
 
 /* AKM suite selectors */
 #define WLAN_AKM_SUITE_8021X		0x000FAC01
diff --git a/include/linux/input/pmic8xxx-pwrkey.h b/include/linux/input/pmic8xxx-pwrkey.h
index 6d2974e..a32eafd 100644
--- a/include/linux/input/pmic8xxx-pwrkey.h
+++ b/include/linux/input/pmic8xxx-pwrkey.h
@@ -24,6 +24,13 @@
  */
 struct pm8xxx_pwrkey_platform_data  {
 	bool pull_up;
+	/* Time delay for pwr-key state change interrupt triggering in micro-
+	 * second. The actual delay can only be one of these eight levels:
+	 * 2 sec, 1 sec, 1/2 sec, 1/4 sec, 1/8 sec, 1/16 sec, 1/32 sec, and
+	 * 1/64 sec. The valid range of kpd_trigger_delay_us is 1/64 second to
+	 * 2 seconds. A value within the valid range will be rounded down to the
+	 * closest level. Any value outside the valid range will be rejected.
+	 */
 	u32  kpd_trigger_delay_us;
 	u32  wakeup;
 };
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 89ac992..b396369 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -35,6 +35,7 @@
 	ION_HEAP_TYPE_SYSTEM,
 	ION_HEAP_TYPE_SYSTEM_CONTIG,
 	ION_HEAP_TYPE_CARVEOUT,
+	ION_HEAP_TYPE_IOMMU,
 	ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
 				 are at the end of this enum */
 	ION_NUM_HEAPS,
@@ -59,6 +60,7 @@
 	ION_HEAP_SMI_ID,
 	ION_HEAP_ADSP_ID,
 	ION_HEAP_AUDIO_ID,
+	ION_HEAP_IOMMU_ID,
 };
 
 #define ION_KMALLOC_HEAP_NAME	"kmalloc"
@@ -66,6 +68,7 @@
 #define ION_EBI1_HEAP_NAME	"EBI1"
 #define ION_ADSP_HEAP_NAME	"adsp"
 #define ION_SMI_HEAP_NAME	"smi"
+#define ION_IOMMU_HEAP_NAME	"iommu"
 
 #define CACHED          1
 #define UNCACHED        0
@@ -99,6 +102,11 @@
  * @name:	used for debug purposes
  * @base:	base address of heap in physical memory if applicable
  * @size:	size of the heap in bytes if applicable
+ * @request_region: function to be called when the number of allocations goes
+ *						from 0 -> 1
+ * @release_region: function to be called when the number of allocations goes
+ *						from 1 -> 0
+ * @setup_region:   function to be called upon ion registration
  *
  * Provided by the board file.
  */
@@ -109,6 +117,9 @@
 	ion_phys_addr_t base;
 	size_t size;
 	enum ion_memory_types memory_type;
+	void (*request_region)(void *);
+	void (*release_region)(void *);
+	void *(*setup_region)(void);
 };
 
 /**
@@ -298,6 +309,65 @@
 int ion_handle_get_flags(struct ion_client *client, struct ion_handle *handle,
 				unsigned long *flags);
 
+
+/**
+ * ion_map_iommu - map the given handle into an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to map
+ * @domain_num - domain number to map to
+ * @partition_num - partition number to allocate iova from
+ * @align - alignment for the iova
+ * @iova_length - length of iova to map. If the iova length is
+ *		greater than the handle length, the remaining
+ *		address space will be mapped to a dummy buffer.
+ * @iova - pointer to store the iova address
+ * @buffer_size - pointer to store the size of the buffer
+ * @flags - flags for options to map
+ *
+ * Maps the handle into the iova space specified via domain number. Iova
+ * will be allocated from the partition specified via partition_num.
+ * Returns 0 on success, negative value on error.
+ */
+int ion_map_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num, unsigned long align,
+			unsigned long iova_length, unsigned long *iova,
+			unsigned long *buffer_size,
+			unsigned long flags);
+
+
+/**
+ * ion_handle_get_size - get the allocated size of a given handle
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to get the size
+ * @size - pointer to store the size
+ *
+ * gives the allocated size of a handle. returns 0 on success, negative
+ * value on error
+ *
+ * NOTE: This is intended to be used only to get a size to pass to map_iommu.
+ * You should *NOT* rely on this for any other usage.
+ */
+
+int ion_handle_get_size(struct ion_client *client, struct ion_handle *handle,
+			unsigned long *size);
+
+/**
+ * ion_unmap_iommu - unmap the handle from an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to unmap
+ * @domain_num - domain to unmap from
+ * @partition_num - partition to unmap from
+ *
+ * Decrement the reference count on the iommu mapping. If the count is
+ * 0, the mapping will be removed from the iommu.
+ */
+void ion_unmap_iommu(struct ion_client *client, struct ion_handle *handle,
+			int domain_num, int partition_num);
+
+
 #else
 static inline struct ion_client *ion_client_create(struct ion_device *dev,
 				     unsigned int heap_mask, const char *name)
@@ -370,6 +440,24 @@
 {
 	return -ENODEV;
 }
+
+static inline int ion_map_iommu(struct ion_client *client,
+			struct ion_handle *handle, int domain_num,
+			int partition_num, unsigned long align,
+			unsigned long iova_length, unsigned long *iova,
+			unsigned long flags)
+{
+	return -ENODEV;
+}
+
+static inline void ion_unmap_iommu(struct ion_client *client,
+			struct ion_handle *handle, int domain_num,
+			int partition_num)
+{
+	return;
+}
+
+
 #endif /* CONFIG_ION */
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h
index f0a3278..9a46128 100644
--- a/include/linux/mfd/pm8xxx/core.h
+++ b/include/linux/mfd/pm8xxx/core.h
@@ -26,6 +26,7 @@
 	PM8XXX_VERSION_8921,
 	PM8XXX_VERSION_8821,
 	PM8XXX_VERSION_8018,
+	PM8XXX_VERSION_8922,
 };
 
 /* PMIC version specific silicon revisions */
@@ -56,6 +57,11 @@
 #define PM8XXX_REVISION_8018_1p1	2
 #define PM8XXX_REVISION_8018_2p0	3
 
+#define PM8XXX_REVISION_8922_TEST	0
+#define PM8XXX_REVISION_8922_1p0	1
+#define PM8XXX_REVISION_8922_1p1	2
+#define PM8XXX_REVISION_8922_2p0	3
+
 struct pm8xxx_drvdata {
 	int			(*pmic_readb) (const struct device *dev,
 						u16 addr, u8 *val);
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index f39c00f..ef08c47 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -184,6 +184,18 @@
 int pm8921_set_max_battery_charge_current(int ma);
 
 /**
+ * pm8921_disable_input_current_limt - disable input current limit
+ *
+ * @disable: disable input curren_limit limit
+ *
+ * Disabling the charge current limit causes current
+ * current limits to have no monitoring. An adequate charger
+ * capable of supplying high current while sustaining VIN_MIN
+ * is required if input current limiting is disabled.
+ */
+int pm8921_disable_input_current_limit(bool disable);
+
+/**
  * pm8921_disable_source_current - disable drawing current from source
  * @disable: true to disable current drawing from source false otherwise
  *
@@ -261,6 +273,10 @@
 {
 	return -ENXIO;
 }
+static inline int pm8921_disable_input_current_limit(bool disable)
+{
+	return -ENXIO;
+}
 static inline int pm8921_set_max_battery_charge_current(int ma)
 {
 	return -ENXIO;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 07890ac..c73fdf8 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -28,6 +28,9 @@
 
 extern unsigned long num_physpages;
 extern unsigned long totalram_pages;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+extern unsigned long total_unmovable_pages;
+#endif
 extern void * high_memory;
 extern int page_cluster;
 
diff --git a/include/linux/msm_audio_mvs.h b/include/linux/msm_audio_mvs.h
index c934aee..2813c8f 100644
--- a/include/linux/msm_audio_mvs.h
+++ b/include/linux/msm_audio_mvs.h
@@ -108,10 +108,18 @@
 
 #define MVS_MAX_VOC_PKT_SIZE 640
 
+struct gsm_header {
+	uint8_t bfi;
+	uint8_t sid;
+	uint8_t taf;
+	uint8_t ufi;
+};
+
 struct q6_msm_audio_mvs_frame {
 	union {
 	uint32_t frame_type;
 	uint32_t packet_rate;
+	struct gsm_header gsm_frame_type;
 	} header;
 	uint32_t len;
 	uint8_t voc_pkt[MVS_MAX_VOC_PKT_SIZE];
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index fc94089..473384b 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -55,6 +55,7 @@
 	PERF_COUNT_HW_BUS_CYCLES		= 6,
 	PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	= 7,
 	PERF_COUNT_HW_STALLED_CYCLES_BACKEND	= 8,
+	PERF_COUNT_HW_L2_CYCLES			= 9,
 
 	PERF_COUNT_HW_MAX,			/* non-ABI */
 };
@@ -219,8 +220,9 @@
 				precise_ip     :  2, /* skid constraint       */
 				mmap_data      :  1, /* non-exec mmap data    */
 				sample_id_all  :  1, /* sample_type all events */
+				single_instance:1, /* per-cpu event if unset */
 
-				__reserved_1   : 45;
+				__reserved_1:44;
 
 	union {
 		__u32		wakeup_events;	  /* wakeup every n events */
diff --git a/include/linux/pmic8058-xoadc.h b/include/linux/pmic8058-xoadc.h
index f72ad66..5163b65 100644
--- a/include/linux/pmic8058-xoadc.h
+++ b/include/linux/pmic8058-xoadc.h
@@ -12,8 +12,8 @@
  * Qualcomm XOADC Driver header file
  */
 
-#ifndef _XOADC_H
-#define _XOADC_H_
+#ifndef _PMIC8058_XOADC_H_
+#define _PMIC8058_XOADC_H_
 
 #include <linux/kernel.h>
 #include <linux/list.h>
diff --git a/include/linux/power/ltc4088-charger.h b/include/linux/power/ltc4088-charger.h
new file mode 100644
index 0000000..7a0bacf
--- /dev/null
+++ b/include/linux/power/ltc4088-charger.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2011, 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 LTC4088_CHARGER_H_
+#define LTC4088_CHARGER_H_
+
+#define LTC4088_CHARGER_DEV_NAME    "ltc4088-charger"
+
+/**
+ * struct ltc4088_charger_platform_data - platform data for LTC4088 charger
+ * @gpio_mode_select_d0: GPIO #pin for D0 charger line
+ * @gpio_mode_select_d1: GPIO #pin for D1 charger line
+ * @gpio_mode_select_d2: GPIO #pin for D2 charger line
+ */
+struct ltc4088_charger_platform_data {
+	unsigned int	gpio_mode_select_d0;
+	unsigned int	gpio_mode_select_d1;
+	unsigned int	gpio_mode_select_d2;
+};
+
+#endif /* LTC4088_CHARGER_H_ */
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 2287c321..cab042b 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -157,6 +157,8 @@
 				     enum power_supply_property psp);
 	void (*external_power_changed)(struct power_supply *psy);
 	void (*set_charged)(struct power_supply *psy);
+	int (*set_current_limit)(struct power_supply *psy, int limit);
+	int (*set_charging_by)(struct power_supply *psy, bool enable);
 
 	/* For APM emulation, think legacy userspace. */
 	int use_for_apm;
@@ -205,6 +207,8 @@
 extern void power_supply_changed(struct power_supply *psy);
 extern int power_supply_am_i_supplied(struct power_supply *psy);
 extern int power_supply_set_battery_charged(struct power_supply *psy);
+extern int power_supply_set_current_limit(struct power_supply *psy, int limit);
+extern int power_supply_set_charging_by(struct power_supply *psy, bool enable);
 
 #if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE)
 extern int power_supply_is_system_supplied(void);
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index c6c6084..3d049ab 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -199,8 +199,11 @@
  * NOTE: not necessary for suspend/resume -- in that case the
  * core stops polling anyway
  */
+#ifdef CONFIG_RFKILL_PM
 void rfkill_resume_polling(struct rfkill *rfkill);
-
+#else
+static inline void rfkill_resume_polling(struct rfkill *rfkill) { }
+#endif
 
 /**
  * rfkill_unregister - Unregister a rfkill structure.
diff --git a/include/linux/usb/ccid_desc.h b/include/linux/usb/ccid_desc.h
new file mode 100644
index 0000000..2d1ae74
--- /dev/null
+++ b/include/linux/usb/ccid_desc.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011, 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 __LINUX_USB_CCID_DESC_H
+#define __LINUX_USB_CCID_DESC_H
+
+/*CCID specification version 1.10*/
+#define CCID1_10                               0x0110
+
+#define SMART_CARD_DEVICE_CLASS                0x0B
+/* Smart Card Device Class Descriptor Type */
+#define CCID_DECRIPTOR_TYPE                    0x21
+
+/* Table 5.3-1 Summary of CCID Class Specific Request */
+#define CCIDGENERICREQ_ABORT                    0x01
+#define CCIDGENERICREQ_GET_CLOCK_FREQUENCIES    0x02
+#define CCIDGENERICREQ_GET_DATA_RATES           0x03
+
+/* 6.1 Command Pipe, Bulk-OUT Messages */
+#define PC_TO_RDR_ICCPOWERON                   0x62
+#define PC_TO_RDR_ICCPOWEROFF                  0x63
+#define PC_TO_RDR_GETSLOTSTATUS                0x65
+#define PC_TO_RDR_XFRBLOCK                     0x6F
+#define PC_TO_RDR_GETPARAMETERS                0x6C
+#define PC_TO_RDR_RESETPARAMETERS              0x6D
+#define PC_TO_RDR_SETPARAMETERS                0x61
+#define PC_TO_RDR_ESCAPE                       0x6B
+#define PC_TO_RDR_ICCCLOCK                     0x6E
+#define PC_TO_RDR_T0APDU                       0x6A
+#define PC_TO_RDR_SECURE                       0x69
+#define PC_TO_RDR_MECHANICAL                   0x71
+#define PC_TO_RDR_ABORT                        0x72
+#define PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY 0x73
+
+/* 6.2 Response Pipe, Bulk-IN Messages */
+#define RDR_TO_PC_DATABLOCK                    0x80
+#define RDR_TO_PC_SLOTSTATUS                   0x81
+#define RDR_TO_PC_PARAMETERS                   0x82
+#define RDR_TO_PC_ESCAPE                       0x83
+#define RDR_TO_PC_DATARATEANDCLOCKFREQUENCY    0x84
+
+/* 6.3 Interrupt-IN Messages */
+#define RDR_TO_PC_NOTIFYSLOTCHANGE             0x50
+#define RDR_TO_PC_HARDWAREERROR                0x51
+
+/* Table 6.2-2 Slot error register when bmCommandStatus = 1 */
+#define CMD_ABORTED                            0xFF
+#define ICC_MUTE                               0xFE
+#define XFR_PARITY_ERROR                       0xFD
+#define XFR_OVERRUN                            0xFC
+#define HW_ERROR                               0xFB
+#define BAD_ATR_TS                             0xF8
+#define BAD_ATR_TCK                            0xF7
+#define ICC_PROTOCOL_NOT_SUPPORTED             0xF6
+#define ICC_CLASS_NOT_SUPPORTED                0xF5
+#define PROCEDURE_BYTE_CONFLICT                0xF4
+#define DEACTIVATED_PROTOCOL                   0xF3
+#define BUSY_WITH_AUTO_SEQUENCE                0xF2
+#define PIN_TIMEOUT                            0xF0
+#define PIN_CANCELLED                          0xEF
+#define CMD_SLOT_BUSY                          0xE0
+
+/* CCID rev 1.1, p.27 */
+#define VOLTS_AUTO                             0x00
+#define VOLTS_5_0                              0x01
+#define VOLTS_3_0                              0x02
+#define VOLTS_1_8                              0x03
+
+/* 6.3.1 RDR_to_PC_NotifySlotChange */
+#define ICC_NOT_PRESENT                        0x00
+#define ICC_PRESENT                            0x01
+#define ICC_CHANGE                             0x02
+#define ICC_INSERTED_EVENT                     (ICC_PRESENT+ICC_CHANGE)
+
+/* Identifies the length of type of subordinate descriptors of a CCID device
+ * Table 5.1-1 Smart Card Device Class descriptors
+ */
+struct usb_ccid_class_descriptor {
+	unsigned char  bLength;
+	unsigned char  bDescriptorType;
+	unsigned short bcdCCID;
+	unsigned char  bMaxSlotIndex;
+	unsigned char  bVoltageSupport;
+	unsigned long  dwProtocols;
+	unsigned long  dwDefaultClock;
+	unsigned long  dwMaximumClock;
+	unsigned char  bNumClockSupported;
+	unsigned long  dwDataRate;
+	unsigned long  dwMaxDataRate;
+	unsigned char  bNumDataRatesSupported;
+	unsigned long  dwMaxIFSD;
+	unsigned long  dwSynchProtocols;
+	unsigned long  dwMechanical;
+	unsigned long  dwFeatures;
+	unsigned long  dwMaxCCIDMessageLength;
+	unsigned char  bClassGetResponse;
+	unsigned char  bClassEnvelope;
+	unsigned short wLcdLayout;
+	unsigned char  bPINSupport;
+	unsigned char  bMaxCCIDBusySlots;
+} __packed;
+#endif
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 4c01f5b..a2251fe 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -189,6 +189,7 @@
  *             connected.
  * @mA_port: The amount of current drawn by the attached B-device.
  * @id_timer: The timer used for polling ID line to detect ACA states.
+ * @xo_handle: TCXO buffer handle
  */
 struct msm_otg {
 	struct otg_transceiver otg;
@@ -220,6 +221,7 @@
 	unsigned mA_port;
 	struct timer_list id_timer;
 	unsigned long caps;
+	struct msm_xo_voter *xo_handle;
 	/*
 	 * Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
 	 * analog regulators while going to low power mode.
diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h
index a096d24..024b913 100644
--- a/include/linux/wakelock.h
+++ b/include/linux/wakelock.h
@@ -33,7 +33,6 @@
 };
 
 struct wake_lock {
-#ifdef CONFIG_HAS_WAKELOCK
 	struct list_head    link;
 	int                 flags;
 	const char         *name;
@@ -49,7 +48,6 @@
 		ktime_t         last_time;
 	} stat;
 #endif
-#endif
 };
 
 #ifdef CONFIG_HAS_WAKELOCK
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 65ca534..4d5d697 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -156,6 +156,9 @@
 #define MSM_CAM_IOCTL_RELEASE_FREE_FRAME \
 	_IOR(MSM_CAM_IOCTL_MAGIC, 46, struct msm_cam_evt_divert_frame *)
 
+#define MSM_CAM_IOCTL_PICT_PP_DIVERT_DONE \
+	_IOR(MSM_CAM_IOCTL_MAGIC, 47, struct msm_pp_frame *)
+
 struct msm_mctl_pp_cmd {
 	int32_t  id;
 	uint16_t length;
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index b4e1981..4694b78 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -203,7 +203,6 @@
 #define MCTL_CMD_GET_FRAME_BUFFER       1  /* reserve a free frame buffer */
 #define MCTL_CMD_PUT_FRAME_BUFFER       2  /* return the free frame buffer */
 #define MCTL_CMD_DIVERT_FRAME_PP_PATH   3  /* divert frame for pp */
-#define MCTL_CMD_DIVERT_FRAME_PP_DONE   4  /* pp done. buf send to app */
 
 /* event typese sending to MCTL PP module */
 #define MCTL_PP_EVENT_NOTUSED           0
@@ -252,6 +251,7 @@
 };
 struct msm_mctl_pp_divert_pp {
 	int path;
+	int enable;
 };
 struct msm_vpe_clock_rate {
 	uint32_t rate;
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index dbdb651..130bc3d 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -198,6 +198,7 @@
 #define HCI_FM_STATION_DBG_PARAM_CMD 12
 #define HCI_FM_ENABLE_TRANS_CMD 13
 #define HCI_FM_DISABLE_TRANS_CMD 14
+#define HCI_FM_GET_TX_CONFIG 15
 
 
 /* Defines for FM TX*/
@@ -241,14 +242,6 @@
 	__u8    rt_data[TX_RT_DATA_LENGTH];
 } __packed;
 
-struct hci_fm_get_trans_conf_rsp {
-	__u8    status;
-	__u8	emphasis;
-	__u8	rds_std;
-	__u32	band_low_limit;
-	__u32	band_high_limit;
-} __packed;
-
 struct hci_fm_mute_mode_req {
 	__u8	hard_mute;
 	__u8	soft_mute;
@@ -428,6 +421,10 @@
 	struct hci_fm_recv_conf_req recv_conf_rsp;
 } __packed;
 
+struct hci_fm_get_trans_conf_rsp {
+	__u8    status;
+	struct hci_fm_trans_conf_req_struct trans_conf_rsp;
+} __packed;
 struct hci_fm_sig_threshold_rsp {
 	__u8    status;
 	__u8    sig_threshold;
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index 43ce153..d40829e 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -148,13 +148,14 @@
 	V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA,
 	V4L2_CID_PRIVATE_TAVARUA_HLSI,
 	/*
-	* Here We have IOCTl's that are specifici to IRIS
-	* (V4L2_CID_PRIVATE_BASE+0x1D--V4L2_CID_PRIVATE_BASE+0x27)
+	* Here we have IOCTl's that are specific to IRIS
+	* (V4L2_CID_PRIVATE_BASE + 0x1E to V4L2_CID_PRIVATE_BASE + 0x27)
 	*/
 	V4L2_CID_PRIVATE_TAVARUA_SET_NOTCH_FILTER =
-		V4L2_CID_PRIVATE_BASE + 0x28,
+		V4L2_CID_PRIVATE_BASE + 0x28, /* IRIS specific command */
 	V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH,
-	/*0x800002a is used for iris specific ioctl*/
+	V4L2_CID_PRIVATE_TAVARUA_DO_CALIBRATION, /* IRIS specific command */
+	V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM,
 
 	V4L2_CID_PRIVATE_TAVARUA_ON_CHANNEL_THRESHOLD =
 		V4L2_CTRL_CLASS_USER + 0x92B,
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 74e14fb..5a15cec 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -240,6 +240,9 @@
 	rwlock_t		adv_entries_lock;
 	struct timer_list	adv_timer;
 
+	struct timer_list	disc_timer;
+	struct timer_list	disc_le_timer;
+
 	struct hci_dev_stats	stat;
 
 	struct sk_buff_head	driver_init;
@@ -1034,6 +1037,7 @@
 int mgmt_remote_name(u16 index, bdaddr_t *bdaddr, u8 status, u8 *name);
 void mgmt_inquiry_started(u16 index);
 void mgmt_inquiry_complete_evt(u16 index, u8 status);
+int mgmt_encrypt_change(u16 index, bdaddr_t *bdaddr, u8 status);
 
 /* LE SMP Management interface */
 int le_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, void *cp);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index ce7ecf1..2d3028d 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -228,6 +228,12 @@
 	__le16 timeout_multiplier;
 } __packed;
 
+#define MGMT_OP_ENCRYPT_LINK		0x0021
+struct mgmt_cp_encrypt_link {
+	bdaddr_t bdaddr;
+	__u8 enable;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
@@ -329,3 +335,10 @@
 	bdaddr_t bdaddr;
 } __packed;
 
+#define MGMT_EV_ENCRYPT_CHANGE		0x0016
+struct mgmt_ev_encrypt_change {
+	bdaddr_t bdaddr;
+	__u8 status;
+} __packed;
+
+
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
index 23dfc40..2583856 100644
--- a/kernel/power/wakelock.c
+++ b/kernel/power/wakelock.c
@@ -52,8 +52,6 @@
 struct wake_lock main_wake_lock;
 suspend_state_t requested_suspend_state = PM_SUSPEND_MEM;
 static struct wake_lock unknown_wakeup;
-/* flag to warn/bug if wakelocks are taken after suspend_noirq */
-static int msm_suspend_check_done;
 static struct wake_lock suspend_backoff_lock;
 
 #define SUSPEND_BACKOFF_THRESHOLD	10
@@ -412,21 +410,11 @@
 #endif
 	if (debug_mask & DEBUG_SUSPEND)
 		pr_info("power_suspend_late return %d\n", ret);
-
-	if (ret == 0)
-		msm_suspend_check_done = 1;
 	return ret;
 }
 
-static int power_resume_early(struct device *dev)
-{
-	msm_suspend_check_done = 0;
-	return 0;
-}
-
 static struct dev_pm_ops power_driver_pm_ops = {
 	.suspend_noirq = power_suspend_late,
-	.resume_noirq = power_resume_early,
 };
 
 static struct platform_driver power_driver = {
@@ -569,24 +557,12 @@
 
 void wake_lock(struct wake_lock *lock)
 {
-	/*
-	 * if wake lock is being called too late in the suspend sequence,
-	 * call bug so we get to analyze the callstack
-	 */
-	BUG_ON(msm_suspend_check_done);
-
 	wake_lock_internal(lock, 0, 0);
 }
 EXPORT_SYMBOL(wake_lock);
 
 void wake_lock_timeout(struct wake_lock *lock, long timeout)
 {
-	/*
-	 * if wake lock is being called too late in the suspend sequence,
-	 * call bug so we get to analyze the callstack
-	 */
-	BUG_ON(msm_suspend_check_done);
-
 	wake_lock_internal(lock, timeout, 1);
 }
 EXPORT_SYMBOL(wake_lock_timeout);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 2480d18..e54ba63 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -646,8 +646,6 @@
 		next = ktime_add(next, tick_period);
 	}
 	local_irq_enable();
-
-	printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id());
 }
 
 /*
@@ -857,10 +855,8 @@
 	}
 
 #ifdef CONFIG_NO_HZ
-	if (tick_nohz_enabled) {
+	if (tick_nohz_enabled)
 		ts->nohz_mode = NOHZ_MODE_HIGHRES;
-		printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id());
-	}
 #endif
 }
 #endif /* HIGH_RES_TIMERS */
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 709dc6d..70ea0df 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -379,6 +379,10 @@
 	unsigned long pfn = page_to_pfn(page);
 
 	totalram_pages++;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+	if (zone_idx(page_zone(page)) != ZONE_MOVABLE)
+		total_unmovable_pages++;
+#endif
 	if (pfn >= num_physpages)
 		num_physpages = pfn + 1;
 
@@ -958,10 +962,17 @@
 	/* reset pagetype flags and makes migrate type to be MOVABLE */
 	undo_isolate_page_range(start_pfn, end_pfn);
 	/* removal success */
-	zone->present_pages -= offlined_pages;
+	if (offlined_pages > zone->present_pages)
+		zone->present_pages = 0;
+	else
+		zone->present_pages -= offlined_pages;
 	zone->zone_pgdat->node_present_pages -= offlined_pages;
 	totalram_pages -= offlined_pages;
 
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+	if (zone_idx(zone) != ZONE_MOVABLE)
+		total_unmovable_pages -= offlined_pages;
+#endif
 	init_per_zone_wmark_min();
 
 	if (!node_present_pages(node)) {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e6b53ea..60ad5e9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -96,6 +96,9 @@
 
 unsigned long totalram_pages __read_mostly;
 unsigned long totalreserve_pages __read_mostly;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+unsigned long total_unmovable_pages __read_mostly;
+#endif
 int percpu_pagelist_fraction;
 gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
 
@@ -174,6 +177,9 @@
 };
 
 EXPORT_SYMBOL(totalram_pages);
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+EXPORT_SYMBOL(total_unmovable_pages);
+#endif
 
 static char * const zone_names[MAX_NR_ZONES] = {
 #ifdef CONFIG_ZONE_DMA
@@ -1485,8 +1491,9 @@
 static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
 		      int classzone_idx, int alloc_flags, long free_pages)
 {
-	/* free_pages my go negative - that's OK */
+	/* free_pages may go negative - that's OK */
 	long min = mark;
+	long lowmem_reserve = z->lowmem_reserve[classzone_idx];
 	int o;
 
 	free_pages -= (1 << order) + 1;
@@ -1495,7 +1502,7 @@
 	if (alloc_flags & ALLOC_HARDER)
 		min -= min / 4;
 
-	if (free_pages <= min + z->lowmem_reserve[classzone_idx])
+	if (free_pages <= min + lowmem_reserve)
 		return false;
 	for (o = 0; o < order; o++) {
 		/* At the next order, this order's pages become unavailable */
diff --git a/mm/slub.c b/mm/slub.c
index adf609e..03bc30b 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -27,6 +27,7 @@
 #include <linux/memory.h>
 #include <linux/math64.h>
 #include <linux/fault-inject.h>
+#include <linux/stacktrace.h>
 
 #include <trace/events/kmem.h>
 
@@ -191,8 +192,12 @@
 /*
  * Tracking user of a slab.
  */
+#define TRACK_ADDRS_COUNT 16
 struct track {
 	unsigned long addr;	/* Called from address */
+#ifdef CONFIG_STACKTRACE
+	unsigned long addrs[TRACK_ADDRS_COUNT];	/* Called from address */
+#endif
 	int cpu;		/* Was running on cpu */
 	int pid;		/* Pid context */
 	unsigned long when;	/* When did the operation occur */
@@ -420,6 +425,24 @@
 	struct track *p = get_track(s, object, alloc);
 
 	if (addr) {
+#ifdef CONFIG_STACKTRACE
+		struct stack_trace trace;
+		int i;
+
+		trace.nr_entries = 0;
+		trace.max_entries = TRACK_ADDRS_COUNT;
+		trace.entries = p->addrs;
+		trace.skip = 3;
+		save_stack_trace(&trace);
+
+		/* See rant in lockdep.c */
+		if (trace.nr_entries != 0 &&
+		    trace.entries[trace.nr_entries - 1] == ULONG_MAX)
+			trace.nr_entries--;
+
+		for (i = trace.nr_entries; i < TRACK_ADDRS_COUNT; i++)
+			p->addrs[i] = 0;
+#endif
 		p->addr = addr;
 		p->cpu = smp_processor_id();
 		p->pid = current->pid;
@@ -444,6 +467,16 @@
 
 	printk(KERN_ERR "INFO: %s in %pS age=%lu cpu=%u pid=%d\n",
 		s, (void *)t->addr, jiffies - t->when, t->cpu, t->pid);
+#ifdef CONFIG_STACKTRACE
+	{
+		int i;
+		for (i = 0; i < TRACK_ADDRS_COUNT; i++)
+			if (t->addrs[i])
+				printk(KERN_ERR "\t%pS\n", (void *)t->addrs[i]);
+			else
+				break;
+	}
+#endif
 }
 
 static void print_tracking(struct kmem_cache *s, void *object)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 45ece89..c33d2ae 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1611,9 +1611,14 @@
 	struct vm_struct *area;
 	void *addr;
 	unsigned long real_size = size;
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+	unsigned long total_pages = total_unmovable_pages;
+#else
+	unsigned long total_pages = totalram_pages;
+#endif
 
 	size = PAGE_ALIGN(size);
-	if (!size || (size >> PAGE_SHIFT) > totalram_pages)
+	if (!size || (size >> PAGE_SHIFT) > total_pages)
 		return NULL;
 
 	area = __get_vm_area_node(size, align, VM_ALLOC, start, end, node,
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h
index 8e6c061..e7ee531 100644
--- a/net/bluetooth/bnep/bnep.h
+++ b/net/bluetooth/bnep/bnep.h
@@ -155,6 +155,7 @@
 	unsigned int  role;
 	unsigned long state;
 	unsigned long flags;
+	atomic_t      terminate;
 	struct task_struct *task;
 
 	struct ethhdr eh;
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index dfadb65..61c946c 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -484,9 +484,11 @@
 
 	init_waitqueue_entry(&wait, current);
 	add_wait_queue(sk_sleep(sk), &wait);
-	while (!kthread_should_stop()) {
+	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
 
+		if (atomic_read(&s->terminate))
+			break;
 		/* RX */
 		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
 			skb_orphan(skb);
@@ -643,9 +645,10 @@
 	down_read(&bnep_session_sem);
 
 	s = __bnep_get_session(req->dst);
-	if (s)
-		kthread_stop(s->task);
-	else
+	if (s) {
+		atomic_inc(&s->terminate);
+		wake_up_process(s->task);
+	} else
 		err = -ENOENT;
 
 	up_read(&bnep_session_sem);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a27358f..e1a90f8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -581,8 +581,11 @@
 		set_bit(HCI_UP, &hdev->flags);
 		hci_notify(hdev, HCI_DEV_UP);
 		if (!test_bit(HCI_SETUP, &hdev->flags) &&
-				hdev->dev_type == HCI_BREDR)
+				hdev->dev_type == HCI_BREDR) {
+			hci_dev_lock_bh(hdev);
 			mgmt_powered(hdev->id, 1);
+			hci_dev_unlock_bh(hdev);
+		}
 	} else {
 		/* Init failed, cleanup */
 		tasklet_kill(&hdev->rx_task);
@@ -668,8 +671,11 @@
 	 * and no tasks are scheduled. */
 	hdev->close(hdev);
 
-	if (hdev->dev_type == HCI_BREDR)
+	if (hdev->dev_type == HCI_BREDR) {
+		hci_dev_lock_bh(hdev);
 		mgmt_powered(hdev->id, 0);
+		hci_dev_unlock_bh(hdev);
+	}
 
 	/* Clear only non-persistent flags */
 	if (test_bit(HCI_MGMT, &hdev->flags))
@@ -1547,8 +1553,11 @@
 
 	if (!test_bit(HCI_INIT, &hdev->flags) &&
 				!test_bit(HCI_SETUP, &hdev->flags) &&
-				hdev->dev_type == HCI_BREDR)
+				hdev->dev_type == HCI_BREDR) {
+		hci_dev_lock_bh(hdev);
 		mgmt_index_removed(hdev->id);
+		hci_dev_unlock_bh(hdev);
+	}
 
 	if (!IS_ERR(hdev->tfm))
 		crypto_free_blkcipher(hdev->tfm);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a6e3485..13d9b71 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -223,12 +223,13 @@
 	sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
 	if (!sent)
 		return;
-
+	hci_dev_lock(hdev);
 	if (!status)
 		memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
 
 	if (test_bit(HCI_MGMT, &hdev->flags))
 		mgmt_set_local_name_complete(hdev->id, sent, status);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -303,6 +304,7 @@
 	if (!status) {
 		__u8 param = *((__u8 *) sent);
 		int old_pscan, old_iscan;
+		hci_dev_lock(hdev);
 
 		old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
 		old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
@@ -320,6 +322,7 @@
 				mgmt_connectable(hdev->id, 1);
 		} else if (old_pscan)
 			mgmt_connectable(hdev->id, 0);
+		hci_dev_unlock(hdev);
 	}
 
 	hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
@@ -859,20 +862,23 @@
 	struct hci_conn *conn;
 
 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+	hci_dev_lock(hdev);
 
 	if (test_bit(HCI_MGMT, &hdev->flags))
 		mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status);
 
 	if (rp->status != 0)
-		return;
+		goto unlock;
 
 	cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
 	if (!cp)
-		return;
+		goto unlock;
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
 	if (conn)
 		conn->pin_length = cp->pin_len;
+unlock:
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -880,10 +886,12 @@
 	struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
 
 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+	hci_dev_lock(hdev);
 
 	if (test_bit(HCI_MGMT, &hdev->flags))
 		mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
 								rp->status);
+	hci_dev_unlock(hdev);
 }
 static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
 				       struct sk_buff *skb)
@@ -910,10 +918,12 @@
 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
 
 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+	hci_dev_lock(hdev);
 
 	if (test_bit(HCI_MGMT, &hdev->flags))
 		mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
 								rp->status);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
@@ -922,10 +932,12 @@
 	struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
 
 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+	hci_dev_lock(hdev);
 
 	if (test_bit(HCI_MGMT, &hdev->flags))
 		mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
 								rp->status);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
@@ -934,9 +946,11 @@
 	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
 
 	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+	hci_dev_lock(hdev);
 
 	mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
 						rp->randomizer, rp->status);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
@@ -995,8 +1009,10 @@
 		hci_conn_check_pending(hdev);
 	} else {
 		set_bit(HCI_INQUIRY, &hdev->flags);
+		hci_dev_lock(hdev);
 		if (test_bit(HCI_MGMT, &hdev->flags))
 			mgmt_inquiry_started(hdev->id);
+		hci_dev_unlock(hdev);
 	}
 }
 
@@ -1506,9 +1522,11 @@
 		clear_bit(HCI_INQUIRY, &hdev->flags);
 
 	hci_req_complete(hdev, HCI_OP_INQUIRY, status);
+	hci_dev_lock(hdev);
 
 	if (test_bit(HCI_MGMT, &hdev->flags))
 		mgmt_inquiry_complete_evt(hdev->id, status);
+	hci_dev_unlock(hdev);
 
 	if (!lmp_le_capable(hdev))
 		hci_conn_check_pending(hdev);
@@ -1709,7 +1727,9 @@
 	BT_DBG("%s status %d", hdev->name, ev->status);
 
 	if (ev->status) {
+		hci_dev_lock(hdev);
 		mgmt_disconnect_failed(hdev->id);
+		hci_dev_unlock(hdev);
 		return;
 	}
 
@@ -1860,6 +1880,9 @@
 			hci_conn_put(conn);
 		} else
 			hci_encrypt_cfm(conn, ev->status, ev->encrypt);
+
+		if (test_bit(HCI_MGMT, &hdev->flags))
+			mgmt_encrypt_change(hdev->id, &conn->dst, ev->status);
 	}
 
 	hci_dev_unlock(hdev);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d63dd1a..4c50713 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3749,9 +3749,9 @@
 
 	/* Initialize rfc in case no rfc option is received */
 	rfc.mode = pi->mode;
-	rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
-	rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
-	rfc.max_pdu_size = L2CAP_DEFAULT_MAX_PDU_SIZE;
+	rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+	rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+	rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
 
 	while (len >= L2CAP_CONF_OPT_SIZE) {
 		len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
@@ -3849,9 +3849,9 @@
 
 	/* Initialize rfc in case no rfc option is received */
 	rfc.mode = pi->mode;
-	rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
-	rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
-	rfc.max_pdu_size = L2CAP_DEFAULT_MAX_PDU_SIZE;
+	rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+	rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+	rfc.max_pdu_size = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
 
 	if ((pi->mode != L2CAP_MODE_ERTM) && (pi->mode != L2CAP_MODE_STREAMING))
 		return;
@@ -5494,6 +5494,7 @@
 		/* TODO MM/PK - What to do if connection is LOCAL_BUSY?  */
 		if (l2cap_pi(sk)->ampchan == chan) {
 			l2cap_pi(sk)->ampchan = NULL;
+			l2cap_pi(sk)->ampcon = NULL;
 			l2cap_amp_move_init(sk);
 		}
 		bh_unlock_sock(sk);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 0e7ff51..b413a9c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -41,8 +41,6 @@
 };
 
 struct disco_interleave {
-	struct timer_list	timer;
-	struct timer_list	le_timer;
 	u16			index;
 	enum scan_mode		mode;
 	int			int_phase;
@@ -208,7 +206,7 @@
 
 	hci_del_off_timer(hdev);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	set_bit(HCI_MGMT, &hdev->flags);
 
@@ -237,7 +235,7 @@
 
 	memcpy(rp.name, hdev->dev_name, sizeof(hdev->dev_name));
 
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return cmd_complete(sk, index, MGMT_OP_READ_INFO, &rp, sizeof(rp));
@@ -377,7 +375,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	up = test_bit(HCI_UP, &hdev->flags);
 	if ((cp->val && up) || (!cp->val && !up)) {
@@ -404,7 +402,7 @@
 	err = 0;
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 	return err;
 }
@@ -467,7 +465,7 @@
 		return cmd_status(sk, index, MGMT_OP_SET_LIMIT_DISCOVERABLE,
 									ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, MGMT_OP_SET_LIMIT_DISCOVERABLE,
@@ -521,7 +519,7 @@
 		mgmt_pending_remove(cmd);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -547,7 +545,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENETDOWN);
@@ -582,7 +580,7 @@
 		mgmt_pending_remove(cmd);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -608,7 +606,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENETDOWN);
@@ -642,7 +640,7 @@
 		mgmt_pending_remove(cmd);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -703,7 +701,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (cp->val)
 		set_bit(HCI_PAIRABLE, &hdev->flags);
@@ -719,7 +717,7 @@
 	err = mgmt_event(MGMT_EV_PAIRABLE, index, &ev, sizeof(ev), sk);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -887,7 +885,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC);
 	if (!uuid) {
@@ -911,7 +909,7 @@
 	err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -936,7 +934,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) {
 		err = hci_uuids_clear(hdev);
@@ -971,7 +969,7 @@
 	err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
 
 unlock:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -995,7 +993,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	hdev->major_class &= ~MGMT_MAJOR_CLASS_MASK;
 	hdev->major_class |= cp->major & MGMT_MAJOR_CLASS_MASK;
@@ -1006,7 +1004,7 @@
 	if (err == 0)
 		err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0);
 
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1028,7 +1026,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	BT_DBG("hci%u enable %d", index, cp->enable);
 
@@ -1046,7 +1044,7 @@
 		err = cmd_complete(sk, index, MGMT_OP_SET_SERVICE_CACHE, NULL,
 									0);
 
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1080,7 +1078,7 @@
 	BT_DBG("hci%u debug_keys %u key_count %u", index, cp->debug_keys,
 								key_count);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	hci_link_keys_clear(hdev);
 
@@ -1118,7 +1116,7 @@
 
 	err = cmd_complete(sk, index, MGMT_OP_LOAD_KEYS, NULL, 0);
 
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1140,7 +1138,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	err = hci_remove_link_key(hdev, &cp->bdaddr);
 	if (err < 0) {
@@ -1163,7 +1161,7 @@
 	}
 
 unlock:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1189,7 +1187,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENETDOWN);
@@ -1225,7 +1223,7 @@
 		mgmt_pending_remove(cmd);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1246,7 +1244,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_GET_CONNECTIONS, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	count = 0;
 	list_for_each(p, &hdev->conn_hash.list) {
@@ -1277,7 +1275,7 @@
 
 unlock:
 	kfree(rp);
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 	return err;
 }
@@ -1302,7 +1300,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENETDOWN);
@@ -1324,12 +1322,70 @@
 		mgmt_pending_remove(cmd);
 
 failed:
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+
+	return err;
+}
+
+static int encrypt_link(struct sock *sk, u16 index, unsigned char *data,
+									u16 len)
+{
+	struct hci_dev *hdev;
+	struct mgmt_cp_encrypt_link *cp;
+	struct hci_cp_set_conn_encrypt enc;
+	struct hci_conn *conn;
+	int err = 0;
+
+	BT_DBG("");
+
+	cp = (void *) data;
+
+	if (len != sizeof(*cp))
+		return cmd_status(sk, index, MGMT_OP_ENCRYPT_LINK, EINVAL);
+
+	hdev = hci_dev_get(index);
+	if (!hdev)
+		return cmd_status(sk, index, MGMT_OP_ENCRYPT_LINK, ENODEV);
+
+	hci_dev_lock(hdev);
+
+	if (!test_bit(HCI_UP, &hdev->flags)) {
+		err = cmd_status(sk, index, MGMT_OP_ENCRYPT_LINK, ENETDOWN);
+		goto failed;
+	}
+
+	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
+					&cp->bdaddr);
+	if (!conn)
+		return cmd_status(sk, index, MGMT_OP_ENCRYPT_LINK, ENOTCONN);
+
+	if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
+		return cmd_status(sk, index, MGMT_OP_ENCRYPT_LINK, EINPROGRESS);
+
+	if (conn->link_mode & HCI_LM_AUTH) {
+		enc.handle = cpu_to_le16(conn->handle);
+		enc.encrypt = cp->enable;
+		err = hci_send_cmd(hdev,
+				HCI_OP_SET_CONN_ENCRYPT, sizeof(enc), &enc);
+	} else {
+		conn->auth_initiator = 1;
+		if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
+			struct hci_cp_auth_requested cp;
+			cp.handle = cpu_to_le16(conn->handle);
+			err = hci_send_cmd(conn->hdev,
+				HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
+		}
+	}
+
+failed:
 	hci_dev_unlock(hdev);
 	hci_dev_put(hdev);
 
 	return err;
 }
 
+
 static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
 									u16 len)
 {
@@ -1351,7 +1407,7 @@
 		return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
 									ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
@@ -1372,7 +1428,7 @@
 		mgmt_pending_remove(cmd);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1395,14 +1451,14 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	hdev->io_capability = cp->io_capability;
 
 	BT_DBG("%s IO capability set to 0x%02x", hdev->name,
 							hdev->io_capability);
 
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return cmd_complete(sk, index, MGMT_OP_SET_IO_CAPABILITY, NULL, 0);
@@ -1507,12 +1563,19 @@
 
 static void discovery_terminated(struct pending_cmd *cmd, void *data)
 {
+	struct hci_dev *hdev;
 	struct mgmt_mode ev = {0};
-	struct disco_interleave *ilp = cmd->param;
 
 	BT_DBG("");
-	del_timer_sync(&ilp->le_timer);
-	del_timer_sync(&ilp->timer);
+	hdev = hci_dev_get(cmd->index);
+	if (!hdev)
+		goto not_found;
+
+	del_timer_sync(&hdev->disc_le_timer);
+	del_timer_sync(&hdev->disc_timer);
+	hci_dev_put(hdev);
+
+not_found:
 	mgmt_event(MGMT_EV_DISCOVERING, cmd->index, &ev, sizeof(ev), NULL);
 
 	list_del(&cmd->list);
@@ -1542,7 +1605,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	BT_DBG("SSP Cap is %d", cp->ssp_cap);
 	io_cap = cp->io_cap;
@@ -1597,7 +1660,7 @@
 	err = 0;
 
 unlock:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1627,7 +1690,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, mgmt_op, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, mgmt_op, ENETDOWN);
@@ -1653,7 +1716,7 @@
 		mgmt_pending_remove(cmd);
 
 done:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1677,7 +1740,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_RESOLVE_NAME, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	cmd = mgmt_pending_add(sk, MGMT_OP_RESOLVE_NAME, index, data, len);
 	if (!cmd) {
@@ -1693,7 +1756,7 @@
 		mgmt_pending_remove(cmd);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1718,7 +1781,7 @@
 		return cmd_status(sk, index, MGMT_OP_SET_CONNECTION_PARAMS,
 									ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr);
 	if (!conn) {
@@ -1735,7 +1798,7 @@
 	err = cmd_status(sk, index, MGMT_OP_SET_CONNECTION_PARAMS, 0);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1759,7 +1822,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_SET_LOCAL_NAME, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	cmd = mgmt_pending_add(sk, MGMT_OP_SET_LOCAL_NAME, index, data, len);
 	if (!cmd) {
@@ -1774,7 +1837,7 @@
 		mgmt_pending_remove(cmd);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -1793,10 +1856,12 @@
 		cmd_complete(cmd->sk, cmd->index, MGMT_OP_STOP_DISCOVERY,
 								NULL, 0);
 		if (cmd->opcode == MGMT_OP_STOP_DISCOVERY) {
-			struct disco_interleave *ilp = cmd->param;
-
-			del_timer_sync(&ilp->le_timer);
-			del_timer_sync(&ilp->timer);
+			struct hci_dev *hdev = hci_dev_get(cmd->index);
+			if (hdev) {
+				del_timer_sync(&hdev->disc_le_timer);
+				del_timer_sync(&hdev->disc_timer);
+				hci_dev_put(hdev);
+			}
 		}
 	}
 
@@ -1825,9 +1890,6 @@
 
 	hdev = hci_dev_get(index);
 
-	if (hdev)
-		hci_dev_lock(hdev);
-
 	if (!hdev || !lmp_le_capable(hdev)) {
 		struct mgmt_mode cp = {0};
 
@@ -1848,8 +1910,8 @@
 
 		err = hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE,
 						sizeof(le_cp), &le_cp);
-		if (err >= 0) {
-			mod_timer(&ilp->le_timer, jiffies +
+		if (err >= 0 && hdev) {
+			mod_timer(&hdev->disc_le_timer, jiffies +
 				msecs_to_jiffies(ilp->int_phase * 1000));
 			ilp->mode = SCAN_LE;
 		} else
@@ -1861,7 +1923,6 @@
 						discovery_terminated, NULL);
 
 done:
-	hci_dev_unlock(hdev);
 	hci_dev_put(hdev);
 }
 
@@ -1873,11 +1934,11 @@
 
 	BT_DBG("hci%d", ilp->index);
 
-	del_timer_sync(&ilp->le_timer);
 	hdev = hci_dev_get(ilp->index);
 
 	if (hdev) {
-		hci_dev_lock(hdev);
+		hci_dev_lock_bh(hdev);
+		del_timer_sync(&hdev->disc_le_timer);
 
 		cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, ilp->index);
 
@@ -1902,7 +1963,7 @@
 			mgmt_pending_remove(cmd);
 		}
 
-		hci_dev_unlock(hdev);
+		hci_dev_unlock_bh(hdev);
 		hci_dev_put(hdev);
 	}
 }
@@ -1919,7 +1980,7 @@
 	hdev = hci_dev_get(ilp->index);
 
 	if (hdev) {
-		hci_dev_lock(hdev);
+		hci_dev_lock_bh(hdev);
 
 		cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, ilp->index);
 
@@ -1938,7 +1999,7 @@
 		} else
 			ilp->mode = SCAN_IDLE;
 
-		hci_dev_unlock(hdev);
+		hci_dev_unlock_bh(hdev);
 		hci_dev_put(hdev);
 	}
 }
@@ -1956,7 +2017,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_START_DISCOVERY, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	cmd = mgmt_pending_add(sk, MGMT_OP_START_DISCOVERY, index, NULL, 0);
 	if (!cmd) {
@@ -2002,16 +2063,17 @@
 		cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, index);
 		if (cmd) {
 			ilp = cmd->param;
-			setup_timer(&ilp->le_timer, disco_le_to,
+			setup_timer(&hdev->disc_le_timer, disco_le_to,
 							(unsigned long) ilp);
-			setup_timer(&ilp->timer, disco_to, (unsigned long) ilp);
-			mod_timer(&ilp->timer,
+			setup_timer(&hdev->disc_timer, disco_to,
+							(unsigned long) ilp);
+			mod_timer(&hdev->disc_timer,
 					jiffies + msecs_to_jiffies(20000));
 		}
 	}
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -2032,7 +2094,7 @@
 	if (!hdev)
 		return cmd_status(sk, index, MGMT_OP_STOP_DISCOVERY, ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (lmp_le_capable(hdev)) {
 		cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, index);
@@ -2056,8 +2118,8 @@
 
 	if (ilp) {
 		ilp->mode = SCAN_IDLE;
-		del_timer_sync(&ilp->le_timer);
-		del_timer_sync(&ilp->timer);
+		del_timer_sync(&hdev->disc_le_timer);
+		del_timer_sync(&hdev->disc_timer);
 	}
 
 	if (err < 0 && cmd)
@@ -2066,7 +2128,7 @@
 	mgmt_event(MGMT_EV_DISCOVERING, index, &mode_cp, sizeof(mode_cp), NULL);
 
 failed:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	if (err < 0)
@@ -2088,7 +2150,7 @@
 		return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
 									ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	if (!test_bit(HCI_UP, &hdev->flags)) {
 		err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
@@ -2118,7 +2180,7 @@
 		mgmt_pending_remove(cmd);
 
 unlock:
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -2142,7 +2204,7 @@
 		return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
 									ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
 								cp->randomizer);
@@ -2152,7 +2214,7 @@
 		err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
 									0);
 
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -2176,7 +2238,7 @@
 		return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
 									ENODEV);
 
-	hci_dev_lock(hdev);
+	hci_dev_lock_bh(hdev);
 
 	err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
 	if (err < 0)
@@ -2186,7 +2248,7 @@
 		err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
 								NULL, 0);
 
-	hci_dev_unlock(hdev);
+	hci_dev_unlock_bh(hdev);
 	hci_dev_put(hdev);
 
 	return err;
@@ -2317,6 +2379,9 @@
 		err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
 									len);
 		break;
+	case MGMT_OP_ENCRYPT_LINK:
+		err = encrypt_link(sk, index, buf + sizeof(*hdr), len);
+		break;
 
 	default:
 		BT_DBG("Unknown op %u", opcode);
@@ -2704,9 +2769,7 @@
 
 	hdev = hci_dev_get(index);
 	if (hdev) {
-		hci_dev_lock_bh(hdev);
 		update_eir(hdev);
-		hci_dev_unlock_bh(hdev);
 		hci_dev_put(hdev);
 	}
 
@@ -2804,7 +2867,7 @@
 				hci_send_cmd(hdev, HCI_OP_INQUIRY,
 							sizeof(cp), &cp);
 				ilp->mode = SCAN_BR;
-				del_timer_sync(&ilp->le_timer);
+				del_timer_sync(&hdev->disc_le_timer);
 			}
 		}
 
@@ -2828,3 +2891,17 @@
 
 	return mgmt_event(MGMT_EV_REMOTE_NAME, index, &ev, sizeof(ev), NULL);
 }
+
+int mgmt_encrypt_change(u16 index, bdaddr_t *bdaddr, u8 status)
+{
+	struct mgmt_ev_encrypt_change ev;
+
+	BT_DBG("hci%u", index);
+
+	bacpy(&ev.bdaddr, bdaddr);
+	ev.status = status;
+
+	return mgmt_event(MGMT_EV_ENCRYPT_CHANGE, index, &ev, sizeof(ev),
+									NULL);
+}
+
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1ac9443..584a7cd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -92,7 +92,7 @@
 	[NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
 	[NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
 	[NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
-	[NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
+	[NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
 	[NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
 
 	[NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
@@ -183,7 +183,7 @@
 	[NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
 	[NL80211_KEY_IDX] = { .type = NLA_U8 },
 	[NL80211_KEY_CIPHER] = { .type = NLA_U32 },
-	[NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
+	[NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
 	[NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
 	[NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
 	[NL80211_KEY_TYPE] = { .type = NLA_U32 },
@@ -3878,7 +3878,8 @@
 		cipher == WLAN_CIPHER_SUITE_WEP104 ||
 		cipher == WLAN_CIPHER_SUITE_TKIP ||
 		cipher == WLAN_CIPHER_SUITE_CCMP ||
-		cipher == WLAN_CIPHER_SUITE_AES_CMAC;
+		cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
+		cipher == WLAN_CIPHER_SUITE_SMS4;
 }
 
 
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4d7b83f..c00a511 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -199,6 +199,10 @@
 		if (params->key_len != WLAN_KEY_LEN_AES_CMAC)
 			return -EINVAL;
 		break;
+	case WLAN_CIPHER_SUITE_SMS4:
+		if (params->key_len != WLAN_KEY_LEN_WAPI_SMS4)
+			return -EINVAL;
+		break;
 	default:
 		/*
 		 * We don't know anything about this algorithm,
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 34712cb..6dd815d 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -27,6 +27,8 @@
 #include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/control.h>
+#include <sound/snd_compress_params.h>
+#include <sound/compress_offload.h>
 #include <sound/info.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -1519,6 +1521,21 @@
 	return result;
 }
 
+static int snd_compressed_ioctl(struct snd_pcm_substream *substream,
+				 unsigned int cmd, void __user *arg)
+{
+	struct snd_pcm_runtime *runtime;
+	int err = 0;
+
+	if (PCM_RUNTIME_CHECK(substream))
+		return -ENXIO;
+	runtime = substream->runtime;
+	if (runtime->status->state != SNDRV_PCM_STATE_OPEN)
+		return -EBADFD;
+	pr_err("%s called with cmd = %d\n", __func__, cmd);
+	err = substream->ops->ioctl(substream, cmd, arg);
+	return err;
+}
 /*
  * drop ioctl
  *
@@ -2573,6 +2590,12 @@
 		snd_pcm_stream_unlock_irq(substream);
 		return res;
 	}
+	case SNDRV_COMPRESS_GET_CAPS:
+	case SNDRV_COMPRESS_GET_CODEC_CAPS:
+	case SNDRV_COMPRESS_SET_PARAMS:
+	case SNDRV_COMPRESS_GET_PARAMS:
+	case SNDRV_COMPRESS_TSTAMP:
+		return snd_compressed_ioctl(substream, cmd, arg);
 	}
 	snd_printd("unknown ioctl = 0x%x\n", cmd);
 	return -ENOTTY;
@@ -2745,7 +2768,7 @@
 
 	pcm_file = file->private_data;
 
-	if (((cmd >> 8) & 0xff) != 'A')
+	if ((((cmd >> 8) & 0xff) != 'A') && (((cmd >> 8) & 0xff) != 'C'))
 		return -ENOTTY;
 
 	return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 3b83532..ba59920 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -39,6 +39,8 @@
 #define BITS_PER_REG 8
 #define TABLA_RX_DAI_ID 1
 #define TABLA_TX_DAI_ID 2
+#define TABLA_CFILT_FAST_MODE 0x00
+#define TABLA_CFILT_SLOW_MODE 0x40
 
 #define TABLA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR)
 
@@ -60,6 +62,7 @@
 	u16 mbhc_reg;
 	u16 int_rbias;
 	u16 ctl_reg;
+	u8 cfilt_sel;
 };
 
 /* Codec supports 2 IIR filters */
@@ -90,6 +93,7 @@
 	bool clock_active;
 	bool config_mode_active;
 	bool mbhc_polling_active;
+	bool fake_insert_context;
 	int buttons_pressed;
 
 	struct tabla_mbhc_calibration *calibration;
@@ -464,13 +468,6 @@
 	SOC_SINGLE_TLV("LINEOUT5 Volume", TABLA_A_RX_LINE_5_GAIN, 0, 12, 1,
 		line_gain),
 
-	SOC_SINGLE("RX1 CHAIN INVERT Switch", TABLA_A_CDC_RX1_B6_CTL, 4, 1, 0),
-	SOC_SINGLE("RX2 CHAIN INVERT Switch", TABLA_A_CDC_RX2_B6_CTL, 4, 1, 0),
-	SOC_SINGLE("RX3 CHAIN INVERT Switch", TABLA_A_CDC_RX3_B6_CTL, 4, 1, 0),
-	SOC_SINGLE("RX4 CHAIN INVERT Switch", TABLA_A_CDC_RX4_B6_CTL, 4, 1, 0),
-	SOC_SINGLE("RX5 CHAIN INVERT Switch", TABLA_A_CDC_RX5_B6_CTL, 4, 1, 0),
-	SOC_SINGLE("RX6 CHAIN INVERT Switch", TABLA_A_CDC_RX6_B6_CTL, 4, 1, 0),
-
 	SOC_SINGLE_TLV("HPHL Volume", TABLA_A_RX_HPH_L_GAIN, 0, 12, 1,
 		line_gain),
 	SOC_SINGLE_TLV("HPHR Volume", TABLA_A_RX_HPH_R_GAIN, 0, 12, 1,
@@ -617,6 +614,10 @@
 		"RX5", "RX6", "RX7"
 };
 
+static const char *rx_dsm_text[] = {
+	"CIC_OUT", "DSM_INV"
+};
+
 static const char *sb_tx1_mux_text[] = {
 	"ZERO", "RMIX1", "RMIX2", "RMIX3", "RMIX4", "RMIX5", "RMIX6", "RMIX7",
 		"DEC1"
@@ -734,6 +735,12 @@
 static const struct soc_enum rx7_mix1_inp2_chain_enum =
 	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_RX7_B1_CTL, 4, 12, rx_mix1_text);
 
+static const struct soc_enum rx4_dsm_enum =
+	SOC_ENUM_SINGLE(TABLA_A_CDC_RX4_B6_CTL, 4, 2, rx_dsm_text);
+
+static const struct soc_enum rx6_dsm_enum =
+	SOC_ENUM_SINGLE(TABLA_A_CDC_RX6_B6_CTL, 4, 2, rx_dsm_text);
+
 static const struct soc_enum sb_tx5_mux_enum =
 	SOC_ENUM_SINGLE(TABLA_A_CDC_CONN_TX_SB_B5_CTL, 0, 9, sb_tx5_mux_text);
 
@@ -835,6 +842,12 @@
 static const struct snd_kcontrol_new rx7_mix1_inp2_mux =
 	SOC_DAPM_ENUM("RX7 MIX1 INP2 Mux", rx7_mix1_inp2_chain_enum);
 
+static const struct snd_kcontrol_new rx4_dsm_mux =
+	SOC_DAPM_ENUM("RX4 DSM MUX Mux", rx4_dsm_enum);
+
+static const struct snd_kcontrol_new rx6_dsm_mux =
+	SOC_DAPM_ENUM("RX6 DSM MUX Mux", rx6_dsm_enum);
+
 static const struct snd_kcontrol_new sb_tx5_mux =
 	SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum);
 
@@ -897,24 +910,12 @@
 static const struct snd_kcontrol_new hphl_switch[] = {
 	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_HPH_L_DAC_CTL, 6, 1, 0)
 };
-static const struct snd_kcontrol_new hphr_switch[] = {
-	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_HPH_R_DAC_CTL, 6, 1, 0)
-};
-static const struct snd_kcontrol_new lineout1_switch[] = {
-	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_LINE_1_DAC_CTL, 6, 1, 0)
-};
-static const struct snd_kcontrol_new lineout2_switch[] = {
-	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_LINE_2_DAC_CTL, 6, 1, 0)
-};
-static const struct snd_kcontrol_new lineout3_switch[] = {
-	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_LINE_3_DAC_CTL, 6, 1, 0)
-};
-static const struct snd_kcontrol_new lineout4_switch[] = {
-	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_LINE_4_DAC_CTL, 6, 1, 0)
-};
-static const struct snd_kcontrol_new lineout5_switch[] = {
-	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_LINE_5_DAC_CTL, 6, 1, 0)
-};
+
+static const struct snd_kcontrol_new lineout3_ground_switch =
+	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_LINE_3_DAC_CTL, 6, 1, 0);
+
+static const struct snd_kcontrol_new lineout4_ground_switch =
+	SOC_DAPM_SINGLE("Switch", TABLA_A_RX_LINE_4_DAC_CTL, 6, 1, 0);
 
 static void tabla_codec_enable_adc_block(struct snd_soc_codec *codec,
 	int enable)
@@ -1184,41 +1185,6 @@
 	return 0;
 }
 
-static void tabla_codec_update_cfilt_usage(struct snd_soc_codec *codec,
-					   u8 cfilt_sel, int inc)
-{
-	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
-	u32 *cfilt_cnt_ptr = NULL;
-	u16 micb_cfilt_reg;
-
-	switch (cfilt_sel) {
-	case TABLA_CFILT1_SEL:
-		cfilt_cnt_ptr = &tabla->cfilt1_cnt;
-		micb_cfilt_reg = TABLA_A_MICB_CFILT_1_CTL;
-		break;
-	case TABLA_CFILT2_SEL:
-		cfilt_cnt_ptr = &tabla->cfilt2_cnt;
-		micb_cfilt_reg = TABLA_A_MICB_CFILT_2_CTL;
-		break;
-	case TABLA_CFILT3_SEL:
-		cfilt_cnt_ptr = &tabla->cfilt3_cnt;
-		micb_cfilt_reg = TABLA_A_MICB_CFILT_3_CTL;
-		break;
-	default:
-		return; /* should not happen */
-	}
-
-	if (inc) {
-		if (!(*cfilt_cnt_ptr)++)
-			snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0x80);
-	} else {
-		/* check if count not zero, decrement
-		 * then check if zero, go ahead disable cfilter
-		 */
-		if ((*cfilt_cnt_ptr) && !--(*cfilt_cnt_ptr))
-			snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0);
-	}
-}
 
 static void tabla_codec_disable_button_presses(struct snd_soc_codec *codec)
 {
@@ -1256,6 +1222,84 @@
 	}
 }
 
+static void tabla_codec_switch_cfilt_mode(struct snd_soc_codec *codec,
+		int mode)
+{
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	u8 reg_mode_val, cur_mode_val;
+	bool mbhc_was_polling = false;
+
+	if (mode)
+		reg_mode_val = TABLA_CFILT_FAST_MODE;
+	else
+		reg_mode_val = TABLA_CFILT_SLOW_MODE;
+
+	cur_mode_val = snd_soc_read(codec,
+					tabla->mbhc_bias_regs.cfilt_ctl) & 0x40;
+
+	if (cur_mode_val != reg_mode_val) {
+		if (tabla->mbhc_polling_active) {
+			tabla_codec_pause_hs_polling(codec);
+			mbhc_was_polling = true;
+		}
+		snd_soc_update_bits(codec,
+			tabla->mbhc_bias_regs.cfilt_ctl, 0x40, reg_mode_val);
+		if (mbhc_was_polling)
+			tabla_codec_start_hs_polling(codec);
+		pr_debug("%s: CFILT mode change (%x to %x)\n", __func__,
+			cur_mode_val, reg_mode_val);
+	} else {
+		pr_debug("%s: CFILT Value is already %x\n",
+			__func__, cur_mode_val);
+	}
+}
+
+static void tabla_codec_update_cfilt_usage(struct snd_soc_codec *codec,
+					   u8 cfilt_sel, int inc)
+{
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	u32 *cfilt_cnt_ptr = NULL;
+	u16 micb_cfilt_reg;
+
+	switch (cfilt_sel) {
+	case TABLA_CFILT1_SEL:
+		cfilt_cnt_ptr = &tabla->cfilt1_cnt;
+		micb_cfilt_reg = TABLA_A_MICB_CFILT_1_CTL;
+		break;
+	case TABLA_CFILT2_SEL:
+		cfilt_cnt_ptr = &tabla->cfilt2_cnt;
+		micb_cfilt_reg = TABLA_A_MICB_CFILT_2_CTL;
+		break;
+	case TABLA_CFILT3_SEL:
+		cfilt_cnt_ptr = &tabla->cfilt3_cnt;
+		micb_cfilt_reg = TABLA_A_MICB_CFILT_3_CTL;
+		break;
+	default:
+		return; /* should not happen */
+	}
+
+	if (inc) {
+		if (!(*cfilt_cnt_ptr)++) {
+			/* Switch CFILT to slow mode if MBHC CFILT being used */
+			if (cfilt_sel == tabla->mbhc_bias_regs.cfilt_sel)
+				tabla_codec_switch_cfilt_mode(codec, 0);
+
+			snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0x80);
+		}
+	} else {
+		/* check if count not zero, decrement
+		 * then check if zero, go ahead disable cfilter
+		 */
+		if ((*cfilt_cnt_ptr) && !--(*cfilt_cnt_ptr)) {
+			snd_soc_update_bits(codec, micb_cfilt_reg, 0x80, 0);
+
+			/* Switch CFILT to fast mode if MBHC CFILT being used */
+			if (cfilt_sel == tabla->mbhc_bias_regs.cfilt_sel)
+				tabla_codec_switch_cfilt_mode(codec, 1);
+		}
+	}
+}
+
 static int tabla_find_k_value(unsigned int ldoh_v, unsigned int cfilt_mv)
 {
 	int rc = -EINVAL;
@@ -1309,10 +1353,13 @@
 {
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	int cfilt_k_val;
+	bool mbhc_was_polling =  false;
 
 	switch (vddio_switch) {
 	case 1:
 		if (tabla->mbhc_polling_active) {
+
+			tabla_codec_pause_hs_polling(codec);
 			/* Enable Mic Bias switch to VDDIO */
 			tabla->cfilt_k_value = snd_soc_read(codec,
 					tabla->mbhc_bias_regs.cfilt_val);
@@ -1326,6 +1373,7 @@
 				tabla->mbhc_bias_regs.mbhc_reg,	0x80, 0x80);
 			snd_soc_update_bits(codec,
 				tabla->mbhc_bias_regs.mbhc_reg,	0x10, 0x00);
+			tabla_codec_start_hs_polling(codec);
 
 			tabla->mbhc_micbias_switched = true;
 			pr_debug("%s: Enabled MBHC Mic bias to VDDIO Switch\n",
@@ -1335,6 +1383,10 @@
 
 	case 0:
 		if (tabla->mbhc_micbias_switched) {
+			if (tabla->mbhc_polling_active) {
+				tabla_codec_pause_hs_polling(codec);
+				mbhc_was_polling = true;
+			}
 			/* Disable Mic Bias switch to VDDIO */
 			if (tabla->cfilt_k_value != 0)
 				snd_soc_update_bits(codec,
@@ -1345,6 +1397,9 @@
 			snd_soc_update_bits(codec,
 				tabla->mbhc_bias_regs.mbhc_reg,	0x10, 0x00);
 
+			if (mbhc_was_polling)
+				tabla_codec_start_hs_polling(codec);
+
 			tabla->mbhc_micbias_switched = false;
 			pr_debug("%s: Disabled MBHC Mic bias to VDDIO Switch\n",
 				__func__);
@@ -1470,6 +1525,8 @@
 {
 	struct snd_soc_codec *codec = w->codec;
 
+	pr_debug("%s %d %s\n", __func__, event, w->name);
+
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_RESET_CTL,
@@ -1528,6 +1585,23 @@
 	}
 	return 0;
 }
+static int tabla_hphr_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	pr_debug("%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
 
 static void hphocp_off_report(struct tabla_priv *tabla,
 	u32 jack_status, int irq)
@@ -1645,6 +1719,8 @@
 		pr_err("%s: Invalid MIC BIAS for MBHC\n", __func__);
 	}
 
+	micbias_regs->cfilt_sel = cfilt;
+
 	switch (cfilt) {
 	case TABLA_CFILT1_SEL:
 		micbias_regs->cfilt_val = TABLA_A_MICB_CFILT_1_VAL;
@@ -1667,6 +1743,25 @@
 	0, NULL, 0),
 };
 
+static int tabla_lineout_dac_event(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+
+	pr_debug("%s %s %d\n", __func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x40);
+		break;
+
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, w->reg, 0x40, 0x00);
+		break;
+	}
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget tabla_dapm_widgets[] = {
 	/*RX stuff */
 	SND_SOC_DAPM_OUTPUT("EAR"),
@@ -1692,8 +1787,10 @@
 	SND_SOC_DAPM_PGA_E("HPHR", TABLA_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
 		tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
 			SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MIXER("HPHR DAC", TABLA_A_RX_HPH_R_DAC_CTL, 7, 0,
-		hphr_switch, ARRAY_SIZE(hphr_switch)),
+
+	SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TABLA_A_RX_HPH_R_DAC_CTL, 7, 0,
+		tabla_hphr_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 	/* Speaker */
 	SND_SOC_DAPM_OUTPUT("LINEOUT1"),
@@ -1718,16 +1815,25 @@
 		tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_MIXER("LINEOUT1 DAC", TABLA_A_RX_LINE_1_DAC_CTL, 7, 0,
-		lineout1_switch, ARRAY_SIZE(lineout1_switch)),
-	SND_SOC_DAPM_MIXER("LINEOUT2 DAC", TABLA_A_RX_LINE_2_DAC_CTL, 7, 0,
-		lineout2_switch, ARRAY_SIZE(lineout2_switch)),
-	SND_SOC_DAPM_MIXER("LINEOUT3 DAC", TABLA_A_RX_LINE_3_DAC_CTL, 7, 0,
-		lineout3_switch, ARRAY_SIZE(lineout3_switch)),
-	SND_SOC_DAPM_MIXER("LINEOUT4 DAC", TABLA_A_RX_LINE_4_DAC_CTL, 7, 0,
-		lineout4_switch, ARRAY_SIZE(lineout4_switch)),
-	SND_SOC_DAPM_MIXER("LINEOUT5 DAC", TABLA_A_RX_LINE_5_DAC_CTL, 7, 0,
-		lineout5_switch, ARRAY_SIZE(lineout5_switch)),
+	SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TABLA_A_RX_LINE_1_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TABLA_A_RX_LINE_2_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TABLA_A_RX_LINE_3_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
+				&lineout3_ground_switch),
+	SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TABLA_A_RX_LINE_4_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
+				&lineout4_ground_switch),
+	SND_SOC_DAPM_DAC_E("LINEOUT5 DAC", NULL, TABLA_A_RX_LINE_5_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_MIXER_E("RX1 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
 		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
@@ -1744,6 +1850,15 @@
 	SND_SOC_DAPM_MIXER_E("RX7 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
 		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
 
+
+	SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0,
+		&rx4_dsm_mux, tabla_codec_reset_interpolator,
+		SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0,
+		&rx6_dsm_mux, tabla_codec_reset_interpolator,
+		SND_SOC_DAPM_PRE_PMU),
+
 	SND_SOC_DAPM_MIXER("RX1 CHAIN", TABLA_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
 	SND_SOC_DAPM_MIXER("RX2 CHAIN", TABLA_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
 
@@ -2022,7 +2137,7 @@
 
 	{"DAC1", "Switch", "RX1 CHAIN"},
 	{"HPHL DAC", "Switch", "RX1 CHAIN"},
-	{"HPHR DAC", "Switch", "RX2 CHAIN"},
+	{"HPHR DAC", NULL, "RX2 CHAIN"},
 
 	{"LINEOUT1", NULL, "LINEOUT1 PA"},
 	{"LINEOUT2", NULL, "LINEOUT2 PA"},
@@ -2036,21 +2151,20 @@
 	{"LINEOUT4 PA", NULL, "LINEOUT4 DAC"},
 	{"LINEOUT5 PA", NULL, "LINEOUT5 DAC"},
 
+	{"LINEOUT1 DAC", NULL, "RX3 MIX1"},
+	{"LINEOUT5 DAC", NULL, "RX7 MIX1"},
+
 	{"RX1 CHAIN", NULL, "RX1 MIX1"},
 	{"RX2 CHAIN", NULL, "RX2 MIX1"},
 	{"RX1 CHAIN", NULL, "ANC"},
 	{"RX2 CHAIN", NULL, "ANC"},
-	{"LINEOUT1 DAC", "Switch", "RX3 MIX1"},
-	{"LINEOUT2 DAC", "Switch", "RX4 MIX1"},
-	{"LINEOUT3 DAC", "Switch", "RX3 MIX1"},
-	{"LINEOUT4 DAC", "Switch", "RX4 MIX1"},
-	{"LINEOUT5 DAC", "Switch", "RX7 MIX1"},
 
 	{"CP", NULL, "RX_BIAS"},
 	{"LINEOUT1 DAC", NULL, "RX_BIAS"},
 	{"LINEOUT2 DAC", NULL, "RX_BIAS"},
 	{"LINEOUT3 DAC", NULL, "RX_BIAS"},
 	{"LINEOUT4 DAC", NULL, "RX_BIAS"},
+	{"LINEOUT5 DAC", NULL, "RX_BIAS"},
 
 	{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
 	{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
@@ -2200,6 +2314,41 @@
 	{"MIC BIAS4 External", NULL, "LDO_H"},
 };
 
+static const struct snd_soc_dapm_route tabla_1_x_lineout_2_to_4_map[] = {
+
+	{"RX4 DSM MUX", "DSM_INV", "RX3 MIX1"},
+	{"RX4 DSM MUX", "CIC_OUT", "RX4 MIX1"},
+
+	{"LINEOUT2 DAC", NULL, "RX4 DSM MUX"},
+
+	{"LINEOUT3 DAC", NULL, "RX5 MIX1"},
+	{"LINEOUT3 DAC GROUND", "Switch", "RX3 MIX1"},
+	{"LINEOUT3 DAC", NULL, "LINEOUT3 DAC GROUND"},
+
+	{"RX6 DSM MUX", "DSM_INV", "RX5 MIX1"},
+	{"RX6 DSM MUX", "CIC_OUT", "RX6 MIX1"},
+
+	{"LINEOUT4 DAC", NULL, "RX6 DSM MUX"},
+	{"LINEOUT4 DAC GROUND", "Switch", "RX4 DSM MUX"},
+	{"LINEOUT4 DAC", NULL, "LINEOUT4 DAC GROUND"},
+};
+
+
+static const struct snd_soc_dapm_route tabla_2_x_lineout_2_to_4_map[] = {
+
+	{"RX4 DSM MUX", "DSM_INV", "RX3 MIX1"},
+	{"RX4 DSM MUX", "CIC_OUT", "RX4 MIX1"},
+
+	{"LINEOUT3 DAC", NULL, "RX4 DSM MUX"},
+
+	{"LINEOUT2 DAC", NULL, "RX5 MIX1"},
+
+	{"RX6 DSM MUX", "DSM_INV", "RX5 MIX1"},
+	{"RX6 DSM MUX", "CIC_OUT", "RX6 MIX1"},
+
+	{"LINEOUT4 DAC", NULL, "RX6 DSM MUX"},
+};
+
 static int tabla_readable(struct snd_soc_codec *ssc, unsigned int reg)
 {
 	return tabla_reg_readable[reg];
@@ -2227,12 +2376,10 @@
 	unsigned int value)
 {
 	int ret;
-	pr_debug("%s: write reg %x val %x\n", __func__, reg, value);
 
 	BUG_ON(reg > TABLA_MAX_REGISTER);
 
 	if (!tabla_volatile(codec, reg)) {
-		pr_debug("writing to cache\n");
 		ret = snd_soc_cache_write(codec, reg, value);
 		if (ret != 0)
 			dev_err(codec->dev, "Cache write to %x failed: %d\n",
@@ -2251,10 +2398,8 @@
 
 	if (!tabla_volatile(codec, reg) && tabla_readable(codec, reg) &&
 		reg < codec->driver->reg_cache_size) {
-		pr_debug("reading from cache\n");
 		ret = snd_soc_cache_read(codec, reg, &val);
 		if (ret >= 0) {
-			pr_debug("register %x, value %x\n", reg, val);
 			return val;
 		} else
 			dev_err(codec->dev, "Cache read from %x failed: %d\n",
@@ -2262,7 +2407,6 @@
 	}
 
 	val = tabla_reg_read(codec->control_data, reg);
-	pr_debug("%s: read reg %x val %x\n", __func__, reg, val);
 	return val;
 }
 
@@ -2769,6 +2913,7 @@
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	struct tabla_mbhc_calibration *calibration = tabla->calibration;
 	short bias_value;
+	u8 cfilt_mode;
 
 	if (!calibration) {
 		pr_err("Error, no tabla calibration\n");
@@ -2787,9 +2932,11 @@
 
 	snd_soc_update_bits(codec, TABLA_A_TX_COM_BIAS, 0xE0, 0xE0);
 
-
-	snd_soc_update_bits(codec,
-		tabla->mbhc_bias_regs.cfilt_ctl, 0x70, 0x00);
+	/* Make sure CFILT is in fast mode, save current mode */
+	cfilt_mode = snd_soc_read(codec,
+		tabla->mbhc_bias_regs.cfilt_ctl);
+	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
+		0x70, 0x00);
 
 	snd_soc_update_bits(codec,
 		tabla->mbhc_bias_regs.ctl_reg, 0x1F, 0x16);
@@ -2812,7 +2959,7 @@
 
 	bias_value = tabla_codec_measure_micbias_voltage(codec, 0);
 	snd_soc_update_bits(codec,
-		tabla->mbhc_bias_regs.cfilt_ctl, 0x40, 0x40);
+		tabla->mbhc_bias_regs.cfilt_ctl, 0x40, cfilt_mode);
 	snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x00);
 
 	return bias_value;
@@ -2824,6 +2971,7 @@
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	struct tabla_mbhc_calibration *calibration = tabla->calibration;
 	int central_bias_enabled = 0;
+	u8 wg_time;
 
 	if (!calibration) {
 		pr_err("Error, no tabla calibration\n");
@@ -2840,20 +2988,28 @@
 			0x81, 0x01);
 		snd_soc_update_bits(codec, tabla->mbhc_bias_regs.mbhc_reg,
 			0x90, 0x00);
+		wg_time = snd_soc_read(codec, TABLA_A_RX_HPH_CNP_WG_TIME) ;
+		wg_time += 1;
 
 		/* Enable HPH Schmitt Trigger */
-		snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x13);
+		snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x11, 0x11);
 		snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x0C,
 			calibration->hph_current << 2);
 
-		/* Turn off HPH PAs during insertion detection to avoid false
-		 * insertion interrupts
+		/* Turn off HPH PAs and DAC's during insertion detection to
+		 * avoid false insertion interrupts
 		 */
 		if (tabla->mbhc_micbias_switched)
 			tabla_codec_switch_micbias(codec, 0);
 		snd_soc_update_bits(codec, TABLA_A_RX_HPH_CNP_EN, 0x30, 0x00);
+		snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_DAC_CTL,
+			0xC0, 0x00);
+		snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_DAC_CTL,
+			0xC0, 0x00);
+		usleep_range(wg_time * 1000, wg_time * 1000);
 
 		/* setup for insetion detection */
+		snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x02, 0x02);
 		snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x2, 0);
 	} else {
 		/* Make sure the HPH schmitt trigger is OFF */
@@ -2953,6 +3109,10 @@
 	tabla->calibration = calibration;
 	tabla_get_mbhc_micbias_regs(codec, &tabla->mbhc_bias_regs);
 
+	/* Put CFILT in fast mode by default */
+	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
+		0x40, TABLA_CFILT_FAST_MODE);
+
 	INIT_DELAYED_WORK(&tabla->btn0_dwork, btn0_lpress_fn);
 	INIT_WORK(&tabla->hphlocp_work, hphlocp_off_report);
 	INIT_WORK(&tabla->hphrocp_work, hphrocp_off_report);
@@ -3162,6 +3322,16 @@
 			0x90, 0x00);
 	snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x00);
 
+	if (priv->fake_insert_context) {
+		pr_debug("%s: fake context interrupt, reset insertion\n",
+			__func__);
+		priv->fake_insert_context = false;
+		tabla_codec_shutdown_hs_polling(codec);
+		tabla_codec_enable_hs_detect(codec, 1);
+		return IRQ_HANDLED;
+	}
+
+
 	ldo_h_on = snd_soc_read(codec, TABLA_A_LDO_H_MODE_1) & 0x80;
 	micb_cfilt_on = snd_soc_read(codec,
 					priv->mbhc_bias_regs.cfilt_ctl) & 0x80;
@@ -3204,7 +3374,25 @@
 	if (mic_voltage > threshold_fake_insert) {
 		pr_debug("%s: Fake insertion interrupt, mic_voltage = %x\n",
 			__func__, mic_voltage);
-		tabla_codec_enable_hs_detect(codec, 1);
+
+		/* Disable HPH trigger and enable MIC line trigger */
+		snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x12, 0x00);
+
+		snd_soc_update_bits(codec, priv->mbhc_bias_regs.mbhc_reg, 0x60,
+			priv->calibration->mic_current << 5);
+		snd_soc_update_bits(codec, priv->mbhc_bias_regs.mbhc_reg,
+			0x80, 0x80);
+		usleep_range(priv->calibration->mic_pid,
+			priv->calibration->mic_pid);
+		snd_soc_update_bits(codec, priv->mbhc_bias_regs.mbhc_reg,
+			0x10, 0x10);
+
+		/* Setup for insertion detection */
+		snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x2, 0);
+		priv->fake_insert_context = true;
+		tabla_enable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
+		snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_INT_CTL, 0x1, 0x1);
+
 	} else if (mic_voltage < threshold_no_mic) {
 		pr_debug("%s: Headphone Detected, mic_voltage = %x\n",
 			__func__, mic_voltage);
@@ -3548,6 +3736,7 @@
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int ret = 0;
 	int i;
+	u8 tabla_version;
 
 	codec->control_data = dev_get_drvdata(codec->dev->parent);
 	control = codec->control_data;
@@ -3571,6 +3760,7 @@
 	tabla->clock_active = false;
 	tabla->config_mode_active = false;
 	tabla->mbhc_polling_active = false;
+	tabla->fake_insert_context = false;
 	tabla->no_mic_headset_override = false;
 	tabla->codec = codec;
 	tabla->pdata = dev_get_platdata(codec->dev->parent);
@@ -3600,6 +3790,27 @@
 			ARRAY_SIZE(audio_i2s_map));
 	}
 	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+
+	tabla_version = snd_soc_read(codec, TABLA_A_CHIP_VERSION);
+	pr_info("%s : Tabla version reg 0x%2x\n", __func__, (u32)tabla_version);
+
+	tabla_version &=  0x1F;
+	pr_info("%s : Tabla version %u\n", __func__, (u32)tabla_version);
+
+	if ((tabla_version == TABLA_VERSION_1_0) ||
+		(tabla_version == TABLA_VERSION_1_1)) {
+		snd_soc_dapm_add_routes(dapm, tabla_1_x_lineout_2_to_4_map,
+			 ARRAY_SIZE(tabla_1_x_lineout_2_to_4_map));
+
+	} else if (tabla_version == TABLA_VERSION_2_0) {
+		snd_soc_dapm_add_routes(dapm, tabla_2_x_lineout_2_to_4_map,
+			 ARRAY_SIZE(tabla_2_x_lineout_2_to_4_map));
+	} else  {
+		pr_err("%s : ERROR.  Unsupported Tabla version 0x%2x\n",
+				__func__, (u32)tabla_version);
+		goto err_pdata;
+	}
+
 	snd_soc_dapm_sync(dapm);
 
 	ret = tabla_request_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION,
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 8c6555b..32fc48f 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -12,6 +12,10 @@
 
 #include <sound/soc.h>
 
+#define TABLA_VERSION_1_0	0
+#define TABLA_VERSION_1_1	1
+#define TABLA_VERSION_2_0	2
+
 #define TABLA_NUM_REGISTERS 0x400
 #define TABLA_MAX_REGISTER (TABLA_NUM_REGISTERS-1)
 #define TABLA_CACHE_SIZE TABLA_NUM_REGISTERS
diff --git a/sound/soc/msm/Kconfig b/sound/soc/msm/Kconfig
index ced46de..9e0549b 100644
--- a/sound/soc/msm/Kconfig
+++ b/sound/soc/msm/Kconfig
@@ -113,8 +113,8 @@
 	 To add support for MSM QDSP6 Soc Audio.
 
 config SND_SOC_MSM8960
-	tristate "SoC Machine driver for MSM8960 boards"
-	depends on ARCH_MSM8960
+	tristate "SoC Machine driver for MSM8960 and APQ8064 boards"
+	depends on ARCH_MSM8960 || ARCH_APQ8064
 	select SND_SOC_VOICE
 	select SND_SOC_QDSP6
 	select SND_SOC_MSM_STUB
@@ -122,7 +122,7 @@
 	select SND_SOC_MSM_HOSTLESS_PCM
 	default n
 	help
-	 To add support for SoC audio on MSM8960 boards
+	 To add support for SoC audio on MSM8960 and APQ8064 boards
 
 config SND_SOC_MSM8660_APQ
         tristate "Soc Machine driver for APQ8060 WM8903 codec"
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index 568fd40..3b257a6 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -56,7 +56,7 @@
 
 obj-$(CONFIG_SND_SOC_MSM_QDSP6_INTF) += qdsp6/
 
-snd-soc-qdsp6-objs := msm-dai-q6.o msm-pcm-q6.o msm-pcm-routing.o msm-dai-fe.o
+snd-soc-qdsp6-objs := msm-dai-q6.o msm-pcm-q6.o msm-pcm-routing.o msm-dai-fe.o msm-compr-q6.o
 obj-$(CONFIG_SND_SOC_VOICE) += msm-pcm-voice.o msm-pcm-voip.o
 snd-soc-qdsp6-objs += msm-pcm-lpa.o msm-pcm-afe.o
 obj-$(CONFIG_SND_SOC_QDSP6) += snd-soc-qdsp6.o
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
new file mode 100644
index 0000000..cf6f1e7
--- /dev/null
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -0,0 +1,567 @@
+/* Copyright (c) 2011, 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/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <asm/dma.h>
+#include <linux/dma-mapping.h>
+#include <linux/android_pmem.h>
+
+#include "msm-compr-q6.h"
+#include "msm-pcm-routing.h"
+
+static struct audio_locks the_locks;
+
+static struct snd_pcm_hardware msm_compr_hardware_playback = {
+	.info =		 (SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				SNDRV_PCM_INFO_MMAP_VALID |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+	.formats =	      SNDRV_PCM_FMTBIT_S16_LE,
+	.rates =		SNDRV_PCM_RATE_8000_48000,
+	.rate_min =	     8000,
+	.rate_max =	     48000,
+	.channels_min =	 1,
+	.channels_max =	 2,
+	.buffer_bytes_max =     1200 * 1024 * 2,
+	.period_bytes_min =	60 * 1024,
+	.period_bytes_max =     1200 * 1024,
+	.periods_min =	  2,
+	.periods_max =	  40,
+	.fifo_size =	    0,
+};
+
+/* Conventional and unconventional sample rate supported */
+static unsigned int supported_sample_rates[] = {
+	8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
+};
+
+static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
+	.count = ARRAY_SIZE(supported_sample_rates),
+	.list = supported_sample_rates,
+	.mask = 0,
+};
+
+static void compr_event_handler(uint32_t opcode,
+		uint32_t token, uint32_t *payload, void *priv)
+{
+	struct compr_audio *compr = priv;
+	struct msm_audio *prtd = &compr->prtd;
+	struct snd_pcm_substream *substream = prtd->substream;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct audio_aio_write_param param;
+	struct audio_buffer *buf = NULL;
+	int i = 0;
+
+	pr_debug("%s opcode =%08x\n", __func__, opcode);
+	switch (opcode) {
+	case ASM_DATA_EVENT_WRITE_DONE: {
+		uint32_t *ptrmem = (uint32_t *)&param;
+		pr_debug("ASM_DATA_EVENT_WRITE_DONE\n");
+		pr_debug("Buffer Consumed = 0x%08x\n", *ptrmem);
+		prtd->pcm_irq_pos += prtd->pcm_count;
+		if (atomic_read(&prtd->start))
+			snd_pcm_period_elapsed(substream);
+		atomic_inc(&prtd->out_count);
+		wake_up(&the_locks.write_wait);
+		if (!atomic_read(&prtd->start)) {
+			prtd->pending_buffer = 1;
+			break;
+		} else
+			prtd->pending_buffer = 0;
+
+		if (runtime->status->hw_ptr >= runtime->control->appl_ptr)
+			break;
+		buf = prtd->audio_client->port[IN].buf;
+		pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
+				__func__, prtd->pcm_count, prtd->out_head);
+		pr_debug("%s:writing buffer[%d] from 0x%08x\n",
+				__func__, prtd->out_head,
+				((unsigned int)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count)));
+
+		param.paddr = (unsigned long)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count);
+		param.len = prtd->pcm_count;
+		param.msw_ts = 0;
+		param.lsw_ts = 0;
+		param.flags = NO_TIMESTAMP;
+		param.uid =  (unsigned long)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count);
+		for (i = 0; i < sizeof(struct audio_aio_write_param)/4;
+					i++, ++ptrmem)
+			pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
+		if (q6asm_async_write(prtd->audio_client,
+					&param) < 0)
+			pr_err("%s:q6asm_async_write failed\n",
+				__func__);
+		else
+			prtd->out_head =
+				(prtd->out_head + 1) & (runtime->periods - 1);
+		break;
+	}
+	case ASM_DATA_CMDRSP_EOS:
+		pr_debug("ASM_DATA_CMDRSP_EOS\n");
+		prtd->cmd_ack = 1;
+		wake_up(&the_locks.eos_wait);
+		break;
+	case APR_BASIC_RSP_RESULT: {
+		switch (payload[0]) {
+		case ASM_SESSION_CMD_RUN: {
+			if (!prtd->pending_buffer &&
+				!atomic_read(&prtd->start))
+				break;
+			pr_debug("%s:writing %d bytes"
+				" of buffer[%d] to dsp\n",
+				__func__, prtd->pcm_count, prtd->out_head);
+			buf = prtd->audio_client->port[IN].buf;
+			pr_debug("%s:writing buffer[%d] from 0x%08x\n",
+				__func__, prtd->out_head,
+				((unsigned int)buf[0].phys
+				+ (prtd->out_head * prtd->pcm_count)));
+			param.paddr = (unsigned long)buf[prtd->out_head].phys;
+			param.len = prtd->pcm_count;
+			param.msw_ts = 0;
+			param.lsw_ts = 0;
+			param.flags = NO_TIMESTAMP;
+			param.uid =  (unsigned long)buf[prtd->out_head].phys;
+			if (q6asm_async_write(prtd->audio_client,
+						&param) < 0)
+				pr_err("%s:q6asm_async_write failed\n",
+					__func__);
+			else
+				prtd->out_head =
+					(prtd->out_head + 1)
+					& (runtime->periods - 1);
+		}
+			break;
+		case ASM_STREAM_CMD_FLUSH:
+			pr_debug("ASM_STREAM_CMD_FLUSH\n");
+			prtd->cmd_ack = 1;
+			wake_up(&the_locks.eos_wait);
+			break;
+		default:
+			break;
+		}
+		break;
+	}
+	default:
+		pr_debug("Not Supported Event opcode[0x%x]\n", opcode);
+		break;
+	}
+}
+
+static int msm_compr_playback_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+	int ret;
+
+	pr_debug("%s\n", __func__);
+	prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
+	prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
+	prtd->pcm_irq_pos = 0;
+	/* rate and channels are sent to audio driver */
+	prtd->samp_rate = runtime->rate;
+	prtd->channel_mode = runtime->channels;
+	prtd->out_head = 0;
+	if (prtd->enabled)
+		return 0;
+
+	ret = q6asm_media_format_block(prtd->audio_client, compr->codec);
+	if (ret < 0)
+		pr_info("%s: CMD Format block failed\n", __func__);
+
+	atomic_set(&prtd->out_count, runtime->periods);
+
+	prtd->enabled = 1;
+	prtd->cmd_ack = 0;
+
+	return 0;
+}
+
+static int msm_compr_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	int ret = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+
+	pr_debug("%s\n", __func__);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		prtd->pcm_irq_pos = 0;
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		pr_debug("%s: Trigger start\n", __func__);
+		q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
+		atomic_set(&prtd->start, 1);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
+		atomic_set(&prtd->start, 0);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		pr_debug("SNDRV_PCM_TRIGGER_PAUSE\n");
+		q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
+		atomic_set(&prtd->start, 0);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static void populate_codec_list(struct compr_audio *compr,
+		struct snd_pcm_runtime *runtime)
+{
+	pr_debug("%s\n", __func__);
+	/* MP3 Block */
+	compr->info.compr_cap.num_codecs = 1;
+	compr->info.compr_cap.min_fragment_size = runtime->hw.period_bytes_min;
+	compr->info.compr_cap.max_fragment_size = runtime->hw.period_bytes_max;
+	compr->info.compr_cap.min_fragments = runtime->hw.periods_min;
+	compr->info.compr_cap.max_fragments = runtime->hw.periods_max;
+	compr->info.compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
+	/* Add new codecs here */
+}
+
+static int msm_compr_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+	struct compr_audio *compr;
+	struct msm_audio *prtd;
+	int ret = 0;
+
+	/* Capture path */
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		return -EINVAL;
+
+	pr_debug("%s\n", __func__);
+	compr = kzalloc(sizeof(struct compr_audio), GFP_KERNEL);
+	if (compr == NULL) {
+		pr_err("Failed to allocate memory for msm_audio\n");
+		return -ENOMEM;
+	}
+	prtd = &compr->prtd;
+	prtd->substream = substream;
+	prtd->audio_client = q6asm_audio_client_alloc(
+				(app_cb)compr_event_handler, compr);
+	if (!prtd->audio_client) {
+		pr_info("%s: Could not allocate memory\n", __func__);
+		kfree(prtd);
+		return -ENOMEM;
+	}
+	runtime->hw = msm_compr_hardware_playback;
+
+	pr_info("%s: session ID %d\n", __func__, prtd->audio_client->session);
+
+	prtd->session_id = prtd->audio_client->session;
+	msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
+			prtd->session_id, substream->stream);
+
+	prtd->cmd_ack = 1;
+
+	ret = snd_pcm_hw_constraint_list(runtime, 0,
+			SNDRV_PCM_HW_PARAM_RATE,
+			&constraints_sample_rates);
+	if (ret < 0)
+		pr_info("snd_pcm_hw_constraint_list failed\n");
+	/* Ensure that buffer size is a multiple of period size */
+	ret = snd_pcm_hw_constraint_integer(runtime,
+			    SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		pr_info("snd_pcm_hw_constraint_integer failed\n");
+
+	prtd->dsp_cnt = 0;
+	prtd->pending_buffer = 1;
+	compr->codec = FORMAT_MP3;
+	populate_codec_list(compr, runtime);
+	runtime->private_data = compr;
+
+	return 0;
+}
+
+static int msm_compr_playback_close(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+	int dir = 0;
+
+	pr_debug("%s\n", __func__);
+
+	dir = IN;
+
+	q6asm_cmd(prtd->audio_client, CMD_CLOSE);
+	q6asm_audio_client_buf_free_contiguous(dir,
+				prtd->audio_client);
+
+	msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
+	SNDRV_PCM_STREAM_PLAYBACK);
+	q6asm_audio_client_free(prtd->audio_client);
+	kfree(prtd);
+	return 0;
+}
+
+static int msm_compr_close(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ret = msm_compr_playback_close(substream);
+	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		ret = EINVAL;
+	return ret;
+}
+static int msm_compr_prepare(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ret = msm_compr_playback_prepare(substream);
+	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		ret = EINVAL;
+	return ret;
+}
+
+static snd_pcm_uframes_t msm_compr_pointer(struct snd_pcm_substream *substream)
+{
+
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+
+	if (prtd->pcm_irq_pos >= prtd->pcm_size)
+		prtd->pcm_irq_pos = 0;
+
+	pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos);
+	return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
+}
+
+static int msm_compr_mmap(struct snd_pcm_substream *substream,
+				struct vm_area_struct *vma)
+{
+	int result = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+
+	pr_debug("%s\n", __func__);
+	prtd->mmap_flag = 1;
+	if (runtime->dma_addr && runtime->dma_bytes) {
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+		result = remap_pfn_range(vma, vma->vm_start,
+				runtime->dma_addr >> PAGE_SHIFT,
+				runtime->dma_bytes,
+				vma->vm_page_prot);
+	} else {
+		pr_err("Physical address or size of buf is NULL");
+		return -EINVAL;
+	}
+	return result;
+}
+
+static int msm_compr_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+	struct snd_dma_buffer *dma_buf = &substream->dma_buffer;
+	struct audio_buffer *buf;
+	int dir, ret;
+
+	pr_debug("%s\n", __func__);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		dir = IN;
+	else
+		return -EINVAL;
+
+	ret = q6asm_open_write(prtd->audio_client, compr->codec);
+	if (ret < 0) {
+		pr_err("%s: Session out open failed\n", __func__);
+		return -ENOMEM;
+	}
+	ret = q6asm_set_io_mode(prtd->audio_client, ASYNC_IO_MODE);
+	if (ret < 0) {
+		pr_err("%s: Set IO mode failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	ret = q6asm_audio_client_buf_alloc_contiguous(dir,
+			prtd->audio_client,
+			runtime->hw.period_bytes_min,
+			runtime->hw.periods_max);
+	if (ret < 0) {
+		pr_err("Audio Start: Buffer Allocation failed "
+					"rc = %d\n", ret);
+		return -ENOMEM;
+	}
+	buf = prtd->audio_client->port[dir].buf;
+
+	pr_debug("%s:buf = %p\n", __func__, buf);
+	dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
+	dma_buf->dev.dev = substream->pcm->card->dev;
+	dma_buf->private_data = NULL;
+	dma_buf->area = buf[0].data;
+	dma_buf->addr =  buf[0].phys;
+	dma_buf->bytes = runtime->hw.buffer_bytes_max;
+	if (!dma_buf->area)
+		return -ENOMEM;
+
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+	return 0;
+}
+
+static int msm_compr_ioctl(struct snd_pcm_substream *substream,
+		unsigned int cmd, void *arg)
+{
+	int rc = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+
+	switch (cmd) {
+	case SNDRV_COMPRESS_GET_CAPS:
+		pr_debug("SNDRV_COMPRESS_GET_CAPS\n");
+		if (copy_to_user((void *) arg, &compr->info.compr_cap,
+			sizeof(struct snd_compr_caps))) {
+			rc = -EFAULT;
+			pr_err("%s: ERROR: copy to user\n", __func__);
+			return rc;
+		}
+		return 0;
+	case SNDRV_COMPRESS_SET_PARAMS:
+		pr_debug("SNDRV_COMPRESS_SET_PARAMS: ");
+		if (copy_from_user(&compr->info.codec_param, (void *) arg,
+			sizeof(struct snd_compr_params))) {
+			rc = -EFAULT;
+			pr_err("%s: ERROR: copy from user\n", __func__);
+			return rc;
+		}
+		switch (compr->info.codec_param.codec.id) {
+		case SND_AUDIOCODEC_MP3:
+			/* For MP3 we dont need any other parameter */
+			pr_debug("SND_AUDIOCODEC_MP3\n");
+			compr->codec = FORMAT_MP3;
+			break;
+		default:
+			pr_debug("FORMAT_LINEAR_PCM\n");
+			compr->codec = FORMAT_LINEAR_PCM;
+			break;
+		}
+		return 0;
+	case SNDRV_PCM_IOCTL1_RESET:
+		prtd->cmd_ack = 0;
+		rc = q6asm_cmd(prtd->audio_client, CMD_FLUSH);
+		if (rc < 0)
+			pr_err("%s: flush cmd failed rc=%d\n", __func__, rc);
+		rc = wait_event_timeout(the_locks.eos_wait,
+			prtd->cmd_ack, 5 * HZ);
+		if (rc < 0)
+			pr_err("Flush cmd timeout\n");
+		prtd->pcm_irq_pos = 0;
+		break;
+	default:
+		break;
+	}
+	return snd_pcm_lib_ioctl(substream, cmd, arg);
+}
+
+static struct snd_pcm_ops msm_compr_ops = {
+	.open	   = msm_compr_open,
+	.hw_params	= msm_compr_hw_params,
+	.close	  = msm_compr_close,
+	.ioctl	  = msm_compr_ioctl,
+	.prepare	= msm_compr_prepare,
+	.trigger	= msm_compr_trigger,
+	.pointer	= msm_compr_pointer,
+	.mmap		= msm_compr_mmap,
+};
+
+static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_card *card = rtd->card->snd_card;
+	int ret = 0;
+
+	if (!card->dev->coherent_dma_mask)
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
+	return ret;
+}
+
+static struct snd_soc_platform_driver msm_soc_platform = {
+	.ops		= &msm_compr_ops,
+	.pcm_new	= msm_asoc_pcm_new,
+};
+
+static __devinit int msm_compr_probe(struct platform_device *pdev)
+{
+	pr_info("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
+	return snd_soc_register_platform(&pdev->dev,
+				   &msm_soc_platform);
+}
+
+static int msm_compr_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_platform(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver msm_compr_driver = {
+	.driver = {
+		.name = "msm-compr-dsp",
+		.owner = THIS_MODULE,
+	},
+	.probe = msm_compr_probe,
+	.remove = __devexit_p(msm_compr_remove),
+};
+
+static int __init msm_soc_platform_init(void)
+{
+	init_waitqueue_head(&the_locks.enable_wait);
+	init_waitqueue_head(&the_locks.eos_wait);
+	init_waitqueue_head(&the_locks.write_wait);
+	init_waitqueue_head(&the_locks.read_wait);
+
+	return platform_driver_register(&msm_compr_driver);
+}
+module_init(msm_soc_platform_init);
+
+static void __exit msm_soc_platform_exit(void)
+{
+	platform_driver_unregister(&msm_compr_driver);
+}
+module_exit(msm_soc_platform_exit);
+
+MODULE_DESCRIPTION("PCM module platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/msm-compr-q6.h b/sound/soc/msm/msm-compr-q6.h
new file mode 100644
index 0000000..6dfbcce
--- /dev/null
+++ b/sound/soc/msm/msm-compr-q6.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, 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 _MSM_COMPR_H
+#define _MSM_COMPR_H
+#include <sound/apr_audio.h>
+#include <sound/q6asm.h>
+#include <sound/snd_compress_params.h>
+#include <sound/compress_offload.h>
+#include <sound/compress_driver.h>
+
+#include "msm-pcm-q6.h"
+
+struct compr_info {
+	struct snd_compr_caps compr_cap;
+	struct snd_compr_codec_caps codec_caps;
+	struct snd_compr_params codec_param;
+};
+
+struct compr_audio {
+	struct msm_audio prtd;
+	struct compr_info info;
+	uint32_t codec;
+};
+
+#endif /*_MSM_COMPR_H*/
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 401c1a9..16d149e 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -151,6 +151,20 @@
 		.ops = &msm_fe_Multimedia_dai_ops,
 		.name = "MultiMedia3",
 	},
+	{
+		.playback = {
+			.stream_name = "MultiMedia4 Playback",
+			.rates = (SNDRV_PCM_RATE_8000_48000 |
+					SNDRV_PCM_RATE_KNOT),
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min =	8000,
+			.rate_max = 48000,
+		},
+		.ops = &msm_fe_Multimedia_dai_ops,
+		.name = "MultiMedia4",
+	},
 	/* FE DAIs created for hostless operation purpose */
 	{
 		.playback = {
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index 29f89ce..f644722 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -131,7 +131,8 @@
 	case APR_BASIC_RSP_RESULT: {
 		switch (payload[0]) {
 		case ASM_SESSION_CMD_RUN: {
-			if (!prtd->pending_buffer)
+			if (!prtd->pending_buffer &&
+				!atomic_read(&prtd->start))
 				break;
 			pr_debug("%s:writing %d bytes"
 				" of buffer to dsp\n",
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 97d0760..3573169 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -125,6 +125,8 @@
 	{INVALID_SESSION, INVALID_SESSION},
 	/* MULTIMEDIA3 */
 	{INVALID_SESSION, INVALID_SESSION},
+	/* MULTIMEDIA4 */
+	{INVALID_SESSION, INVALID_SESSION},
 };
 
 static void msm_pcm_routing_build_matrix(int fedai_id, int dspst_id,
@@ -615,6 +617,9 @@
 	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_PRI_I2S_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_PRI_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
@@ -627,6 +632,9 @@
 	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_0_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
@@ -639,6 +647,9 @@
 	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_HDMI_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_HDMI_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = {
@@ -651,6 +662,9 @@
 	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_BT_SCO_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
@@ -663,6 +677,9 @@
 	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_INT_FM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
@@ -675,6 +692,9 @@
 	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AFE_PCM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
@@ -687,6 +707,9 @@
 	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_AUXPCM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
@@ -1014,6 +1037,7 @@
 	SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("MM_DL4", "MultiMedia4 Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
@@ -1111,16 +1135,19 @@
 	{"PRI_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"PRI_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"PRI_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
 
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
 
 	{"HDMI Mixer", "MultiMedia1", "MM_DL1"},
 	{"HDMI Mixer", "MultiMedia2", "MM_DL2"},
 	{"HDMI Mixer", "MultiMedia3", "MM_DL3"},
+	{"HDMI Mixer", "MultiMedia4", "MM_DL4"},
 	{"HDMI", NULL, "HDMI Mixer"},
 
 	{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
@@ -1130,16 +1157,19 @@
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
 
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
 
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
 
 	{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
@@ -1153,6 +1183,7 @@
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
 
 	{"PRI_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index db7552d..b7fc82a 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -31,6 +31,7 @@
 	MSM_FRONTEND_DAI_MULTIMEDIA1 = 0,
 	MSM_FRONTEND_DAI_MULTIMEDIA2,
 	MSM_FRONTEND_DAI_MULTIMEDIA3,
+	MSM_FRONTEND_DAI_MULTIMEDIA4,
 	MSM_FRONTEND_DAI_CS_VOICE,
 	MSM_FRONTEND_DAI_VOIP,
 	MSM_FRONTEND_DAI_AFE_RX,
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 268d2e5..ab7f9f7 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -1202,6 +1202,9 @@
 	case FORMAT_WMA_V10PRO:
 		open.format = WMA_V10PRO;
 		break;
+	case FORMAT_MP3:
+		open.format = MP3;
+		break;
 	default:
 		pr_err("%s: Invalid format[%d]\n", __func__, format);
 		goto fail_cmd;
@@ -1865,7 +1868,26 @@
 
 	q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
 	fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
-	fmt.format = format;
+	switch (format) {
+	case FORMAT_V13K:
+		fmt.format = V13K_FS;
+		break;
+	case FORMAT_EVRC:
+		fmt.format = EVRC_FS;
+		break;
+	case FORMAT_AMRWB:
+		fmt.format = AMRWB_FS;
+		break;
+	case FORMAT_AMRNB:
+		fmt.format = AMRNB_FS;
+		break;
+	case FORMAT_MP3:
+		fmt.format = MP3;
+		break;
+	default:
+		pr_err("Invalid format[%d]\n", format);
+		goto fail_cmd;
+	}
 	fmt.cfg_size = 0;
 
 	rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
diff --git a/sound/soc/soc-dsp.c b/sound/soc/soc-dsp.c
index 6b0c215..706954b 100644
--- a/sound/soc/soc-dsp.c
+++ b/sound/soc/soc-dsp.c
@@ -627,6 +627,10 @@
 	struct snd_soc_dsp_params *dsp_params;
 	int ret = 0;
 
+	if ((cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) ||
+				(cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH))
+		return ret;
+
 	list_for_each_entry(dsp_params, &fe->dsp[stream].be_clients, list_be) {
 
 		struct snd_pcm_substream *be_substream =
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index c168366..225b292 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -366,6 +366,7 @@
 BUILTIN_OBJS += $(OUTPUT)builtin-record.o
 BUILTIN_OBJS += $(OUTPUT)builtin-report.o
 BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
+BUILTIN_OBJS += $(OUTPUT)builtin-periodic.o
 BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
 BUILTIN_OBJS += $(OUTPUT)builtin-top.o
 BUILTIN_OBJS += $(OUTPUT)builtin-script.o
diff --git a/tools/perf/builtin-periodic.c b/tools/perf/builtin-periodic.c
new file mode 100644
index 0000000..70a0e2b
--- /dev/null
+++ b/tools/perf/builtin-periodic.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+/*
+ *	A very simple perf program to periodically print the performance
+ *	counter reqested on the command line to standard out at the rate
+ *	specified.
+ *
+ *	This is valuable for showing the output in a simple plot or
+ *	exporting the counter data for post processing.  No attempt
+ *	to process the data is made.
+ *
+ *	Scaling is not supported, use only as many counters as are
+ *	provided by the hardware.
+ *
+ *	Math functions are support to combine counter results by using
+ *	the -m flag.
+ *
+ *	The -r -w flags supports user signalling for input. This assumes
+ *	that a pipe/fifo is needed so the -rw cmd line arg is a string
+ *	that is the name of the named pipe to open for read/write.  User
+ *	sends data on the read pipe to the process to collect a sample.
+ *	Commands are also supported on the pipe.
+ *
+ */
+
+#include "perf.h"
+#include "builtin.h"
+#include "util/util.h"
+#include "util/parse-options.h"
+#include "util/parse-events.h"
+#include "util/event.h"
+#include "util/evsel.h"
+#include "util/evlist.h"
+#include "util/debug.h"
+#include "util/header.h"
+#include "util/cpumap.h"
+#include "util/thread.h"
+#include <signal.h>
+#include <sys/types.h>
+
+#define PERF_PERIODIC_ERROR -1
+
+/* number of pieces of data on each read. */
+#define DATA_SIZE 2
+
+#define DEFAULT_FIFO_NAME "xxbadFiFo"
+#define MAX_NAMELEN 50
+
+struct perf_evlist *evsel_list;
+
+/*
+ * command line variables and settings
+ * Default to current process, no_inherit, process
+ */
+static pid_t target_pid = -1; /* all */
+static bool system_wide;
+static int cpumask = -1;  /* all */
+static int ncounts;
+static int ms_sleep = 1000;  /* 1 second */
+static char const *operations = "nnnnnnnnnnnnnnnn";  /* nop */
+static bool math_enabled;
+static bool calc_delta;
+static double old_accum, accum;
+static int math_op_index;
+static char const *wfifo_name = DEFAULT_FIFO_NAME;
+static char const *rfifo_name = DEFAULT_FIFO_NAME;
+static bool use_fifo;
+static bool is_ratio;
+static FILE *fd_in, *fd_out;
+
+static FILE *tReadFifo, *tWriteFifo;
+
+/*
+ * Raw results from perf, we track the current value and
+ * the old value.
+ */
+struct perf_raw_results_s {
+	u64 values;
+	u64 old_value;
+};
+
+/*
+ * Everything we need to support a perf counter across multiple
+ * CPUs.  We need to support multiple file descriptors (perf_fd)
+ * because perf requires a fd per counter, so 1 per core enabled.
+ *
+ * Raw results values are calculated across all the cores as they
+ * are read.
+ */
+struct perf_setup_s {
+	int event_index;
+	struct perf_event_attr *attr;
+	int perf_fd[MAX_NR_CPUS];
+	pid_t pid;
+	int cpu;
+	int flags;
+	int group;
+	struct perf_raw_results_s data;
+	struct perf_raw_results_s totals;
+	struct perf_raw_results_s output;
+};
+
+static void do_cleanup(void)
+{
+	if (fd_in) {
+		if (0 != fclose(fd_in))
+			error("Error closing fd_in\n");
+	}
+	if (fd_out) {
+		if (0 != fclose(fd_out))
+			error("Error closing fd_out\n");
+	}
+	if (use_fifo) {
+		if (0 != unlink(rfifo_name))
+			error("Error unlinking rfifo\n");
+		if (0 != unlink(wfifo_name))
+			error("Error unlinking wfifo\n");
+	}
+}
+
+/*
+ * Unexpected signal for error indication, cleanup
+ */
+static int sig_dummy;
+static void sig_do_cleanup(int sig)
+{
+	sig_dummy = sig;
+	do_cleanup();
+	exit(0);
+}
+
+#define PERIODIC_MAX_STRLEN 100
+/*
+ * Delay for either a timed period or the wait on the read_fifo
+ */
+static void delay(unsigned long milli)
+{
+	char tmp_stg[PERIODIC_MAX_STRLEN];
+	int done;
+	int ret;
+
+	if (use_fifo) {
+		do {
+			done = true;
+			ret = fscanf(tReadFifo, "%s", tmp_stg);
+			if (ret == 0)
+				return;
+			/*
+			 * Look for a command request, and if we get a command
+			 * Need to process and then wait again w/o sending data.
+			 */
+			if (strncmp(tmp_stg, "PID", strnlen(tmp_stg,
+				PERIODIC_MAX_STRLEN)) == 0) {
+				fprintf(fd_out, " %u\n", getpid());
+				fflush(fd_out);
+				done = false;
+			} else if (strncmp(tmp_stg, "EXIT",
+					strnlen(tmp_stg, PERIODIC_MAX_STRLEN))
+						== 0) {
+				do_cleanup();
+				exit(0);
+			}
+
+		} while (done != true);
+	} else
+		usleep(milli*1000);
+}
+
+/*
+ * Create a perf counter event.
+ * Some interesting behaviour that is not documented anywhere else:
+ * the CPU will not work if out of range.
+ * The CPU will only work for a single CPU, so to collect the counts
+ * on the system in SMP based systems a counter needs to be created
+ * for each CPU.
+ */
+static int create_perf_counter(struct perf_setup_s *p)
+{
+	struct cpu_map *cpus;
+	int cpu;
+
+	cpus = cpu_map__new(NULL);
+	if (p == NULL)
+		return PERF_PERIODIC_ERROR;
+	for (cpu = 0; cpu < cpus->nr; cpu++) {
+		p->perf_fd[cpu] = sys_perf_event_open(p->attr, target_pid, cpu,
+					-1, 0);
+		if (p->perf_fd[cpu] < 0)
+			return PERF_PERIODIC_ERROR;
+	}
+	return 0;
+}
+
+/*
+ * Perf init setup
+ */
+static int perf_setup_init(struct perf_setup_s *p)
+{
+	if (p == NULL)
+		return PERF_PERIODIC_ERROR;
+
+	bzero(p, sizeof(struct perf_setup_s));
+	p->group = -1;
+	p->flags = 0;
+
+	p->output.values = 0;
+	p->output.old_value = 0;
+	p->data.values = 0;
+	p->data.old_value = 0;
+	p->totals.old_value = 0;
+	p->totals.values = 0;
+
+	return 0;
+}
+
+/*
+ * Read in ALL the performance counters configured for the CPU,
+ * one performance monitor per core that was configured during
+ * "all" mode
+ */
+static int perf_setup_read(struct perf_setup_s *p)
+{
+	u64 data[DATA_SIZE];
+	int i, status;
+
+	p->totals.values = 0;
+	p->data.values = 0;
+	for (i = 0; i < MAX_NR_CPUS; i++) {
+		if (p->perf_fd[i] == 0)
+			continue;
+		status = read(p->perf_fd[i], &data, sizeof(data));
+		p->data.values += data[0];
+		p->totals.values += data[0];
+	}
+
+	/*
+	 * Normally we show totals, we want to support
+	 * showing deltas from the previous value so external apps do not have
+	 * to do this...
+	 */
+	if (calc_delta) {
+		p->output.values = p->data.values - p->data.old_value;
+		p->data.old_value = p->data.values;
+	} else
+		p->output.values = p->totals.values;
+	return 0;
+}
+
+static int perf_setup_show(struct perf_setup_s *p)
+{
+	if (p == NULL)
+		return PERF_PERIODIC_ERROR;
+	fprintf(fd_out, " %llu", p->output.values);
+	return 0;
+}
+
+
+static const char * const periodic_usage[] = {
+	"perf periodic [<options>]",
+	NULL
+};
+
+static const struct option options[] = {
+	OPT_CALLBACK('e', "event", &evsel_list, "event",
+	"event selector. use 'perf list' to list available events",
+	 parse_events),
+	OPT_STRING('m', "math-operations", &operations, "nnnnnn",
+	"math operation to perform on values collected asmd in order"),
+	OPT_STRING('r', "readpipe", &rfifo_name, "xxbadFiFo",
+	"wait for a user input fifo - will be created"),
+	OPT_STRING('w', "writepipe", &wfifo_name, "xxbadFifo",
+	"write data out on this pipe - pipe is created"),
+	OPT_INTEGER('i', "increment", &ncounts,
+	"number of times periods to count/iterate (default 0-forever)"),
+	OPT_INTEGER('p', "pid", &target_pid,
+	"stat events on existing process id"),
+	OPT_INTEGER('c', "cpumask", &cpumask,
+	"cpumask to enable counters, default all (-1)"),
+	OPT_INTEGER('s', "sleep", &ms_sleep,
+	"how long to sleep in ms between each sample (default 1000)"),
+	OPT_BOOLEAN('a', "all-cpus", &system_wide,
+	"system-wide collection from all CPUs overrides cpumask"),
+	OPT_BOOLEAN('d', "delta", &calc_delta,
+	"calculate and display the delta values math funcs will use delta"),
+	OPT_INCR('v', "verbose", &verbose,
+	"be more verbose (show counter open errors, etc)"),
+	OPT_END()
+};
+
+/*
+ * After every period we reset any math that was performed.
+ */
+static void reset_math(void)
+{
+	math_op_index = 0;
+	old_accum = accum;
+	accum = 0;
+}
+
+static void do_math_op(struct perf_setup_s *p)
+{
+	if (!math_enabled)
+		return;
+	switch (operations[math_op_index++]) {
+	case 'm':
+		accum *= (double)p->output.values; break;
+	case 'a':
+		accum += (double)p->output.values; break;
+	case 's':
+		accum -= (double)p->output.values; break;
+	case 'd':
+		accum /= (double)p->output.values; break;
+	case 'z':
+		accum =  0; break;
+	case 't':
+		accum =  (double)p->output.values; break; /*transfer*/
+	case 'T':
+		accum +=  old_accum; break; /*total*/
+	case 'i':	/* ignore */
+	default:
+		break;
+	}
+}
+
+int cmd_periodic(int argc, const char **argv, const char *prefix __used)
+{
+	int status = 0;
+	int c, i;
+	struct perf_setup_s *p[MAX_COUNTERS];
+	struct perf_evsel *counter;
+	FILE *fp;
+	int nr_counters = 0;
+
+	evsel_list = perf_evlist__new(NULL, NULL);
+	if (evsel_list == NULL)
+		return -ENOMEM;
+
+	argc = parse_options(argc, argv, options, periodic_usage,
+		PARSE_OPT_STOP_AT_NON_OPTION);
+
+	if (system_wide)
+		cpumask = -1;
+
+	/*
+	 * The r & w option redirects stdout to a newly created pipe and
+	 * waits for input on the read pipe before continuing
+	 */
+	fd_in = stdin;
+	fd_out = stdout;
+	if (strncmp(rfifo_name, DEFAULT_FIFO_NAME,
+				strnlen(rfifo_name, MAX_NAMELEN))) {
+		fp = fopen(rfifo_name, "r");
+		if (fp != NULL) {
+			fclose(fp);
+			remove(rfifo_name);
+		}
+		if (mkfifo(rfifo_name, 0777) == -1) {
+			error("Could not open read fifo\n");
+			do_cleanup();
+			return PERF_PERIODIC_ERROR;
+		}
+		tReadFifo = fopen(rfifo_name, "r+");
+		if (tReadFifo == 0) {
+			do_cleanup();
+			error("Could not open read fifo file\n");
+			return PERF_PERIODIC_ERROR;
+		}
+		use_fifo = true;
+	}
+	if (strncmp(wfifo_name, DEFAULT_FIFO_NAME,
+				strnlen(wfifo_name, MAX_NAMELEN)))  {
+		fp = fopen(wfifo_name, "r");
+		if (fp != NULL) {
+			fclose(fp);
+			remove(wfifo_name);
+		}
+		if (mkfifo(wfifo_name, 0777) == -1) {
+			do_cleanup();
+			error("Could not open write fifo\n");
+			return PERF_PERIODIC_ERROR;
+		}
+		fd_out = fopen(wfifo_name, "w+");
+		if (fd_out == 0) {
+			do_cleanup();
+			error("Could not open write fifo file\n");
+			return PERF_PERIODIC_ERROR;
+		}
+		tWriteFifo = fd_out;
+	}
+
+	math_enabled = (operations[0] != 'n');
+
+	/*
+	 * If we don't ignore SIG_PIPE then when the other side
+	 * of a pipe closes we shutdown too...
+	 */
+	signal(SIGPIPE, SIG_IGN);
+	signal(SIGINT, sig_do_cleanup);
+	signal(SIGQUIT, sig_do_cleanup);
+	signal(SIGKILL, sig_do_cleanup);
+	signal(SIGTERM, sig_do_cleanup);
+
+	i = 0;
+	list_for_each_entry(counter, &evsel_list->entries, node) {
+		p[i] = malloc(sizeof(struct perf_setup_s));
+		if (p[i] == NULL) {
+			error("Error allocating perf_setup_s\n");
+			do_cleanup();
+			return PERF_PERIODIC_ERROR;
+		}
+		bzero(p[i], sizeof(struct perf_setup_s));
+		perf_setup_init(p[i]);
+		p[i]->attr = &(counter->attr);
+		p[i]->event_index = counter->idx;
+		if (create_perf_counter(p[i]) < 0) {
+			do_cleanup();
+			die("Not all events could be opened.\n");
+			return PERF_PERIODIC_ERROR;
+		}
+		i++;
+		nr_counters++;
+	}
+	i = 0;
+	while (1) {
+
+		/*
+		 * Wait first otherwise single sample will print w/o signal
+		 * when using the -u (user signal) flag
+		 */
+		delay(ms_sleep);
+
+		/*
+		 * Do the collection, read and then perform any math operations
+		 */
+		for (c = 0; c < nr_counters; c++) {
+			status = perf_setup_read(p[c]);
+			do_math_op(p[c]);
+		}
+
+		/*
+		 * After all collection and math, we perform one last math
+		 * to allow totaling, if enabled etc, then either printout
+		 * a single float value when the math is enabled or ...
+		 */
+		if (math_enabled) {
+			do_math_op(p[c]);
+			if (is_ratio)
+				fprintf(fd_out, "%#f\n", accum*100);
+			else
+				fprintf(fd_out, "%#f\n", accum);
+		} else {
+			/*
+			 * ... print out one integer value for each counter
+			 */
+			for (c = 0; c < nr_counters; c++)
+				status = perf_setup_show(p[c]);
+			fprintf(fd_out, "\n");
+		}
+
+		/*
+		 * Did the user give us an iteration count?
+		 */
+		if ((ncounts != 0) && (++i >= ncounts))
+			break;
+		reset_math();
+		fflush(fd_out); /* make sure data is flushed out the pipe*/
+	}
+
+	do_cleanup();
+
+	return status;
+}
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 4702e24..889ff68 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -26,6 +26,7 @@
 extern int cmd_record(int argc, const char **argv, const char *prefix);
 extern int cmd_report(int argc, const char **argv, const char *prefix);
 extern int cmd_stat(int argc, const char **argv, const char *prefix);
+extern int cmd_periodic(int argc, const char **argv, const char *prefix);
 extern int cmd_timechart(int argc, const char **argv, const char *prefix);
 extern int cmd_top(int argc, const char **argv, const char *prefix);
 extern int cmd_script(int argc, const char **argv, const char *prefix);
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index ec635b7..32f6673 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -320,6 +320,7 @@
 		{ "report",	cmd_report,	0 },
 		{ "bench",	cmd_bench,	0 },
 		{ "stat",	cmd_stat,	0 },
+		{ "periodic",   cmd_periodic,   0 },
 		{ "timechart",	cmd_timechart,	0 },
 		{ "top",	cmd_top,	0 },
 		{ "annotate",	cmd_annotate,	0 },