Merge "Asoc: msm: Configure sampling rate to 48KHz for quad-mic topology" into msm-3.0
diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt
new file mode 100644
index 0000000..eb3986e
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/arch_timer.txt
@@ -0,0 +1,23 @@
+* ARM architected timer
+
+ARM Cortex-A7 and Cortex-A15 have a per-core architected timer, which
+provides a per-cpu local timer.
+
+The timer is attached to a GIC to deliver its two per-processor
+interrupts (one for the secure mode, one for the non-secure mode).
+
+** Timer node properties:
+
+- compatible : Should be "arm,armv7-timer"
+
+- interrupts : One or two interrupts for secure and non-secure mode
+
+- clock-frequency : The frequency of the main counter, in Hz. Optional.
+
+Example:
+
+	timer {
+		compatible = "arm,armv7-timer"";
+		interrupts = <1 13 0xf08 1 14 0xf08>;
+		clock-frequency = <100000000>;
+	};
diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
new file mode 100644
index 0000000..9cf57fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
@@ -0,0 +1,29 @@
+Fixed Voltage regulators
+
+Required properties:
+- compatible: Must be "regulator-fixed";
+
+Optional properties:
+- gpio: gpio to use for enable control
+- startup-delay-us: startup time in microseconds
+- enable-active-high: Polarity of GPIO is Active high
+If this property is missing, the default assumed is Active low.
+
+Any property defined as part of the core regulator
+binding, defined in regulator.txt, can also be used.
+However a fixed voltage regulator is expected to have the
+regulator-min-microvolt and regulator-max-microvolt
+to be the same.
+
+Example:
+
+	abc: fixedregulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "fixed-supply";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		gpio = <&gpio1 16 0>;
+		startup-delay-us = <70000>;
+		enable-active-high;
+		regulator-boot-on
+	};
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
new file mode 100644
index 0000000..82bef20
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -0,0 +1,54 @@
+Voltage/Current Regulators
+
+Optional properties:
+- regulator-name: A string used as a descriptive name for regulator outputs
+- regulator-min-microvolt: smallest voltage consumers may set
+- regulator-max-microvolt: largest voltage consumers may set
+- regulator-microvolt-offset: Offset applied to voltages to compensate for voltage drops
+- regulator-min-microamp: smallest current consumers may set
+- regulator-max-microamp: largest current consumers may set
+- regulator-always-on: boolean, regulator should never be disabled
+- regulator-boot-on: bootloader/firmware enabled regulator
+- <name>-supply: phandle to the parent supply/regulator node
+
+Example:
+
+	xyzreg: regulator@0 {
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <2500000>;
+		regulator-always-on;
+		vin-supply = <&vin>;
+	};
+
+Regulator Consumers:
+Consumer nodes can reference one or more of its supplies/
+regulators using the below bindings.
+
+- <name>-supply: phandle to the regulator node
+
+These are the same bindings that a regulator in the above
+example used to reference its own supply, in which case
+its just seen as a special case of a regulator being a
+consumer itself.
+
+Example of a consumer device node (mmc) referencing two
+regulators (twl-reg1 and twl-reg2),
+
+	twl-reg1: regulator@0 {
+		...
+		...
+		...
+	};
+
+	twl-reg2: regulator@1 {
+		...
+		...
+		...
+	};
+
+	mmc: mmc@0x0 {
+		...
+		...
+		vmmc-supply = <&twl-reg1>;
+		vmmcaux-supply = <&twl-reg2>;
+	};
diff --git a/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt b/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
new file mode 100644
index 0000000..cf727d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/slimbus/slim-msm-ctrl.txt
@@ -0,0 +1,38 @@
+Qualcomm SLIMBUS controller
+
+Required properties:
+
+ - reg : Offset and length of the register region(s) for the device
+ - reg-names : Register region name(s) referenced in reg above
+	 Required register resource entries are:
+	 "slimbus_physical": Physical adderss of controller register blocks
+	 "slimbus_bam_physical": Physical address of Bus Access Module (BAM)
+				 for this controller
+ - compatible : should be "qcom,slim-msm"
+ - cell-index : SLIMBUS number used for this controller
+ - interrupts : Interrupt numbers used by this controller
+ - interrupt-names : Required interrupt resource entries are:
+	"slimbus_irq" : Interrupt for SLIMBUS core
+	"slimbus_bam_irq" : Interrupt for controller core's BAM
+
+Optional property:
+ - reg entry for slew rate : If slew rate control register is provided, this
+	 entry should be used.
+ - reg-name for slew rate: "slimbus_slew_reg"
+ - qcom,min-clk-gear : Minimum clock gear at which this controller can be run
+		 (range: 1-10)
+		 Default value will be 1 if this entry is not specified
+ - qcom,max-clk-gear: Maximum clock gear at which this controller can be run
+		 (range: 1-10)
+		 Default value will be 10 if this entry is not specified
+Example:
+	slim@fe12f000 {
+		cell-index = <1>;
+		compatible = "qcom,slim-msm";
+		reg = <0xfe12f000 0x35000>,
+		      <0xfe104000 0x20000>;
+		reg-names = "slimbus_physical", "slimbus_bam_physical";
+		interrupts = <0 163 0 0 164 0>;
+		interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+		qcom,min-clk-gear = <10>;
+	};
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index a0ea117..8c8cc12 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -23,8 +23,9 @@
 	};
 
 	timer {
-		compatible = "qcom,msm-qtimer";
+		compatible = "qcom,msm-qtimer", "arm,armv7-timer";
 		interrupts = <1 2 0>;
+		clock-frequency = <19200000>;
 	};
 
 	serial@f991f000 {
@@ -85,6 +86,17 @@
 		spi-max-frequency = <24000000>;
 	};
 
+	slim@fe12f000 {
+		cell-index = <1>;
+		compatible = "qcom,slim-msm";
+		reg = <0xfe12f000 0x35000>,
+		      <0xfe104000 0x20000>;
+		reg-names = "slimbus_physical", "slimbus_bam_physical";
+		interrupts = <0 163 0 0 164 0>;
+		interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+		qcom,min-clk-gear = <10>;
+	};
+
 	qcom,spmi@fc4c0000 {
 		cell-index = <0>;
 		compatible = "qcom,spmi-pmic-arb";
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index c671d32..1d0584e 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -8,6 +8,7 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PANIC_TIMEOUT=5
 CONFIG_ASHMEM=y
 CONFIG_EMBEDDED=y
 # CONFIG_PERF_EVENTS is not set
@@ -34,7 +35,7 @@
 # CONFIG_MSM_HW3D is not set
 # CONFIG_QSD_AUDIO is not set
 # CONFIG_SURF_FFA_GPIO_KEYPAD is not set
-CONFIG_MSM_JTAG=y
+CONFIG_MSM_WATCHDOG=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_VMSPLIT_2G=y
diff --git a/arch/arm/configs/fsm9xxx_defconfig b/arch/arm/configs/fsm9xxx_defconfig
index 80252d8..b3e5b87 100644
--- a/arch/arm/configs/fsm9xxx_defconfig
+++ b/arch/arm/configs/fsm9xxx_defconfig
@@ -8,6 +8,7 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PANIC_TIMEOUT=5
 CONFIG_KALLSYMS_ALL=y
 CONFIG_ASHMEM=y
 CONFIG_EMBEDDED=y
@@ -33,6 +34,7 @@
 # CONFIG_MSM_HW3D is not set
 # CONFIG_QSD_AUDIO is not set
 # CONFIG_SURF_FFA_GPIO_KEYPAD is not set
+CONFIG_MSM_WATCHDOG=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_VMSPLIT_2G=y
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index d1c607e..8594562 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -97,6 +97,9 @@
 CONFIG_DIAG_CHAR=y
 CONFIG_HW_RANDOM=y
 CONFIG_DCC_TTY=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_SPIDEV=m
 CONFIG_SPMI=y
 CONFIG_SPMI_MSM_PMIC_ARB=y
 CONFIG_MSM_QPNP=y
diff --git a/arch/arm/configs/msm7627-perf_defconfig b/arch/arm/configs/msm7627-perf_defconfig
deleted file mode 100644
index 82fc695..0000000
--- a/arch/arm/configs/msm7627-perf_defconfig
+++ /dev/null
@@ -1,307 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-perf"
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_ASHMEM=y
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_ARCH_MSM=y
-CONFIG_ARCH_MSM7X27=y
-# CONFIG_MSM_STACKED_MEMORY is not set
-CONFIG_MSM7X00A_USE_DG_TIMER=y
-# CONFIG_MSM_FIQ_SUPPORT is not set
-CONFIG_MSM_SMD=y
-CONFIG_MSM_SMD_PKG4=y
-CONFIG_MSM_ONCRPCROUTER=y
-CONFIG_MSM_RMT_STORAGE_CLIENT=y
-# CONFIG_MSM_HW3D is not set
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_VFP=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# 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 is not set
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_IPV6_OPTIMISTIC_DAD=y
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-CONFIG_IPV6_MIP6=y
-CONFIG_IPV6_TUNNEL=y
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_LOG=y
-CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_DCCP=y
-CONFIG_NF_CT_PROTO_SCTP=y
-CONFIG_NF_CT_PROTO_UDPLITE=y
-CONFIG_NF_CONNTRACK_AMANDA=y
-CONFIG_NF_CONNTRACK_FTP=y
-CONFIG_NF_CONNTRACK_H323=y
-CONFIG_NF_CONNTRACK_IRC=y
-CONFIG_NF_CONNTRACK_NETBIOS_NS=y
-CONFIG_NF_CONNTRACK_PPTP=y
-CONFIG_NF_CONNTRACK_SANE=y
-CONFIG_NF_CONNTRACK_SIP=y
-CONFIG_NF_CONNTRACK_TFTP=y
-CONFIG_NF_CT_NETLINK=y
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
-CONFIG_NETFILTER_XT_TARGET_MARK=y
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
-CONFIG_NETFILTER_XT_MATCH_COMMENT=y
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_HELPER=y
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
-CONFIG_NETFILTER_XT_MATCH_LENGTH=y
-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_QUOTA=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
-CONFIG_NETFILTER_XT_MATCH_STATE=y
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
-CONFIG_NETFILTER_XT_MATCH_STRING=y
-CONFIG_NETFILTER_XT_MATCH_TIME=y
-CONFIG_NETFILTER_XT_MATCH_U32=y
-CONFIG_NF_CONNTRACK_IPV4=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_AH=y
-CONFIG_IP_NF_MATCH_ECN=y
-CONFIG_IP_NF_MATCH_TTL=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_NF_NAT=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_NETMAP=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP_NF_ARP_MANGLE=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_HTB=y
-CONFIG_NET_CLS_U32=y
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=y
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_IBS=y
-CONFIG_BT_MSM_SLEEP=y
-CONFIG_MSM_BT_POWER=y
-# CONFIG_WIRELESS_EXT_SYSFS is not set
-CONFIG_RFKILL=y
-# CONFIG_RFKILL_PM is not set
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
-CONFIG_MTD=y
-CONFIG_MTD_TESTS=m
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=8
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_MISC_DEVICES=y
-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_MD=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_DM_CRYPT=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_LIBRA_SDIOIF=m
-CONFIG_SLIP=y
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_MSM_LEGACY=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_KEYCHORD=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_INPUT_GPIO=y
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM_HS=y
-CONFIG_DIAG_CHAR=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_MSM=y
-# CONFIG_HWMON is not set
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_VIDEO_DEV=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-CONFIG_MSM_KGSL=y
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-CONFIG_FB=y
-CONFIG_FB_MSM=y
-# CONFIG_FB_MSM_BACKLIGHT is not set
-CONFIG_FB_MSM_TRIPLE_BUFFER=y
-CONFIG_FB_MSM_MDP30=y
-CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_ARM is not set
-CONFIG_SND_SOC=y
-CONFIG_SND_MSM_SOC=y
-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_ROOT_HUB_TT=y
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_EHCI_MSM_72K=y
-CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
-CONFIG_USB_EHSET_TEST_FIXTURE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_MSM_72K=y
-CONFIG_USB_G_ANDROID=y
-CONFIG_RMNET_SMD_CTL_CHANNEL="DATA12_CNTL"
-CONFIG_RMNET_SMD_DATA_CHANNEL="DATA12"
-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
-CONFIG_MMC_TEST=m
-CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
-CONFIG_SWITCH=y
-CONFIG_SWITCH_GPIO=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DEBUG=y
-CONFIG_STAGING=y
-CONFIG_ANDROID=y
-CONFIG_ANDROID_BINDER_IPC=y
-CONFIG_ANDROID_LOGGER=y
-CONFIG_ANDROID_RAM_CONSOLE=y
-CONFIG_ANDROID_TIMED_GPIO=y
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT4_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_YAFFS_FS=y
-CONFIG_YAFFS_DISABLE_TAGS_ECC=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm7627_defconfig b/arch/arm/configs/msm7627_defconfig
deleted file mode 100644
index c6dfdc4..0000000
--- a/arch/arm/configs/msm7627_defconfig
+++ /dev/null
@@ -1,312 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_ASHMEM=y
-CONFIG_EMBEDDED=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-CONFIG_ARCH_MSM=y
-CONFIG_ARCH_MSM7X27=y
-# CONFIG_MSM_STACKED_MEMORY is not set
-CONFIG_MSM7X00A_USE_DG_TIMER=y
-# CONFIG_MSM_FIQ_SUPPORT is not set
-CONFIG_MSM_SMD=y
-CONFIG_MSM_SMD_PKG4=y
-CONFIG_MSM_ONCRPCROUTER=y
-CONFIG_MSM_RMT_STORAGE_CLIENT=y
-# CONFIG_MSM_HW3D is not set
-CONFIG_STRICT_MEMORY_RWX=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_VFP=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_WAKELOCK=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# 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 is not set
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_IPV6_OPTIMISTIC_DAD=y
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-CONFIG_IPV6_MIP6=y
-CONFIG_IPV6_TUNNEL=y
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_LOG=y
-CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_DCCP=y
-CONFIG_NF_CT_PROTO_SCTP=y
-CONFIG_NF_CT_PROTO_UDPLITE=y
-CONFIG_NF_CONNTRACK_AMANDA=y
-CONFIG_NF_CONNTRACK_FTP=y
-CONFIG_NF_CONNTRACK_H323=y
-CONFIG_NF_CONNTRACK_IRC=y
-CONFIG_NF_CONNTRACK_NETBIOS_NS=y
-CONFIG_NF_CONNTRACK_PPTP=y
-CONFIG_NF_CONNTRACK_SANE=y
-CONFIG_NF_CONNTRACK_SIP=y
-CONFIG_NF_CONNTRACK_TFTP=y
-CONFIG_NF_CT_NETLINK=y
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
-CONFIG_NETFILTER_XT_TARGET_MARK=y
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
-CONFIG_NETFILTER_XT_MATCH_COMMENT=y
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_HELPER=y
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
-CONFIG_NETFILTER_XT_MATCH_LENGTH=y
-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_QUOTA=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
-CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
-CONFIG_NETFILTER_XT_MATCH_STATE=y
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
-CONFIG_NETFILTER_XT_MATCH_STRING=y
-CONFIG_NETFILTER_XT_MATCH_TIME=y
-CONFIG_NETFILTER_XT_MATCH_U32=y
-CONFIG_NF_CONNTRACK_IPV4=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_AH=y
-CONFIG_IP_NF_MATCH_ECN=y
-CONFIG_IP_NF_MATCH_TTL=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_NF_NAT=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_NETMAP=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP_NF_ARP_MANGLE=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_HTB=y
-CONFIG_NET_CLS_U32=y
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=y
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_IBS=y
-CONFIG_BT_MSM_SLEEP=y
-CONFIG_MSM_BT_POWER=y
-# CONFIG_WIRELESS_EXT_SYSFS is not set
-CONFIG_RFKILL=y
-# CONFIG_RFKILL_PM is not set
-CONFIG_GENLOCK=y
-CONFIG_GENLOCK_MISCDEVICE=y
-CONFIG_MTD=y
-CONFIG_MTD_TESTS=m
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=8
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_MISC_DEVICES=y
-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_MD=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_DM_CRYPT=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_LIBRA_SDIOIF=m
-CONFIG_SLIP=y
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_MODE_SLIP6=y
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_MSM_LEGACY=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_KEYCHORD=y
-CONFIG_INPUT_UINPUT=y
-CONFIG_INPUT_GPIO=y
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_MSM_HS=y
-CONFIG_DIAG_CHAR=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_DCC_TTY=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_MSM=y
-# CONFIG_HWMON is not set
-CONFIG_MSM_KGSL=y
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-CONFIG_FB=y
-CONFIG_FB_MSM=y
-# CONFIG_FB_MSM_BACKLIGHT is not set
-CONFIG_FB_MSM_TRIPLE_BUFFER=y
-CONFIG_FB_MSM_MDP30=y
-CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_ARM is not set
-CONFIG_SND_SOC=y
-CONFIG_SND_MSM_SOC=y
-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_ROOT_HUB_TT=y
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_EHCI_MSM_72K=y
-CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
-CONFIG_USB_EHSET_TEST_FIXTURE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_MSM_72K=y
-CONFIG_USB_G_ANDROID=y
-CONFIG_RMNET_SMD_CTL_CHANNEL="DATA12_CNTL"
-CONFIG_RMNET_SMD_DATA_CHANNEL="DATA12"
-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
-CONFIG_MMC_TEST=m
-CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SDIO_SUPPORT=y
-CONFIG_SWITCH=y
-CONFIG_SWITCH_GPIO=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DEBUG=y
-CONFIG_STAGING=y
-CONFIG_ANDROID=y
-CONFIG_ANDROID_BINDER_IPC=y
-CONFIG_ANDROID_LOGGER=y
-CONFIG_ANDROID_RAM_CONSOLE=y
-CONFIG_ANDROID_TIMED_GPIO=y
-CONFIG_ANDROID_LOW_MEMORY_KILLER=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT4_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_YAFFS_FS=y
-CONFIG_YAFFS_DISABLE_TAGS_ECC=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-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_DETECT_HUNG_TASK=y
-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_DEBUG_LIST=y
-CONFIG_LATENCYTOP=y
-CONFIG_DEBUG_PAGEALLOC=y
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 2375654..8c2e3a6 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -65,6 +65,7 @@
 CONFIG_MSM_PIL_MODEM=y
 CONFIG_MSM_PIL_QDSP6V3=y
 CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_DSPS=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_RPM_STATS_LOG=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 23cd17e..0e83888 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -64,6 +64,7 @@
 CONFIG_MSM_PIL_MODEM=y
 CONFIG_MSM_PIL_QDSP6V3=y
 CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_DSPS=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_RPM_STATS_LOG=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 68870b6..3384b48 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -9,7 +9,7 @@
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_RT_GROUP_SCHED=y
 CONFIG_NAMESPACES=y
 # CONFIG_UTS_NS is not set
@@ -69,6 +69,7 @@
 CONFIG_MSM_PIL_QDSP6V4=y
 CONFIG_MSM_PIL_RIVA=y
 CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_DSPS=y
 CONFIG_MSM_PIL_GSS=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_MODEM_8960=y
@@ -289,6 +290,7 @@
 CONFIG_SPI=y
 CONFIG_SPI_QUP=y
 CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_MASTER=y
 CONFIG_SLIMBUS_MSM_CTRL=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
@@ -300,6 +302,8 @@
 CONFIG_PM8921_CHARGER=y
 CONFIG_PM8921_BMS=y
 CONFIG_SENSORS_PM8XXX_ADC=y
+CONFIG_HWMON=y
+CONFIG_SENSORS_EPM_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8960=y
 CONFIG_THERMAL_PM8XXX=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index ccf448d..064b787 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -8,7 +8,7 @@
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
+CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_RT_GROUP_SCHED=y
 CONFIG_NAMESPACES=y
 # CONFIG_UTS_NS is not set
@@ -68,6 +68,7 @@
 CONFIG_MSM_PIL_QDSP6V4=y
 CONFIG_MSM_PIL_RIVA=y
 CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_DSPS=y
 CONFIG_MSM_PIL_GSS=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_MODEM_8960=y
@@ -293,6 +294,7 @@
 CONFIG_SPI=y
 CONFIG_SPI_QUP=y
 CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_MASTER=y
 CONFIG_SLIMBUS_MSM_CTRL=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
@@ -304,6 +306,8 @@
 CONFIG_PM8921_CHARGER=y
 CONFIG_PM8921_BMS=y
 CONFIG_SENSORS_PM8XXX_ADC=y
+CONFIG_HWMON=y
+CONFIG_SENSORS_EPM_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8960=y
 CONFIG_THERMAL_PM8XXX=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index c9ce881..f5193da 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -201,6 +201,7 @@
 CONFIG_SENSORS_PM8XXX_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8960=y
+CONFIG_THERMAL_PM8XXX=y
 CONFIG_MFD_PM8018_CORE=y
 CONFIG_WCD9310_CODEC=y
 CONFIG_REGULATOR_PM8XXX=y
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 827305d..2098288 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -9,11 +9,17 @@
 
 #ifdef CONFIG_ARM_ARCH_TIMER
 int arch_timer_register(struct arch_timer *);
+int arch_timer_of_register(void);
 #else
 static inline int arch_timer_register(struct arch_timer *at)
 {
 	return -ENXIO;
 }
+
+static inline int arch_timer_of_register(void)
+{
+	return -ENXIO;
+}
 #endif
 
 #endif
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 4dccb04..31c5f5f 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -92,7 +92,6 @@
 #define xchg(ptr,x) \
 	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 
-extern asmlinkage void __backtrace(void);
 extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
 
 struct mm_struct;
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index c6ff17c..8c5b581 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -18,6 +18,7 @@
 #include <linux/jiffies.h>
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
+#include <linux/of_irq.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 
@@ -272,13 +273,10 @@
 	.stop	= arch_timer_stop,
 };
 
-int __init arch_timer_register(struct arch_timer *at)
+static int __init arch_timer_common_register(void)
 {
 	int err;
 
-	if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ))
-		return -EINVAL;
-
 	err = arch_timer_available();
 	if (err)
 		return err;
@@ -296,7 +294,6 @@
 	set_delay_fn(read_current_timer_delay_loop);
 #endif
 
-	arch_timer_ppi = at->res[0].start;
 	err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
 				 "arch_timer", arch_timer_evt);
 	if (err) {
@@ -305,8 +302,7 @@
 		goto out_free;
 	}
 
-	if (at->res[1].start > 0 && (at->res[1].flags & IORESOURCE_IRQ)) {
-		arch_timer_ppi2 = at->res[1].start;
+	if (arch_timer_ppi2) {
 		err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler,
 					 "arch_timer", arch_timer_evt);
 		if (err) {
@@ -334,3 +330,54 @@
 
 	return err;
 }
+
+int __init arch_timer_register(struct arch_timer *at)
+{
+	if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ))
+		return -EINVAL;
+
+	arch_timer_ppi = at->res[0].start;
+
+	if (at->res[1].start > 0 && (at->res[1].flags & IORESOURCE_IRQ))
+		arch_timer_ppi2 = at->res[1].start;
+
+	return arch_timer_common_register();
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id arch_timer_of_match[] __initconst = {
+	{ .compatible	= "arm,armv7-timer",	},
+	{},
+};
+
+int __init arch_timer_of_register(void)
+{
+	struct device_node *np;
+	u32 freq;
+	int ret;
+
+	np = of_find_matching_node(NULL, arch_timer_of_match);
+	if (!np) {
+		pr_err("arch_timer: can't find DT node\n");
+		return -ENODEV;
+	}
+
+	/* Try to determine the frequency from the device tree or CNTFRQ */
+	if (!of_property_read_u32(np, "clock-frequency", &freq))
+		arch_timer_rate = freq;
+
+	ret = irq_of_parse_and_map(np, 0);
+	if (ret <= 0) {
+		pr_err("arch_timer: interrupt not specified in timer node\n");
+		return -ENODEV;
+	}
+	arch_timer_ppi = ret;
+	ret = irq_of_parse_and_map(np, 1);
+	if (ret > 0)
+		arch_timer_ppi2 = ret;
+	pr_info("arch_timer: found %s irqs %d %d\n",
+		np->name, arch_timer_ppi, arch_timer_ppi2);
+
+	return arch_timer_common_register();
+}
+#endif
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 263eaaf..c035a96 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -49,9 +49,6 @@
 
 extern void fpundefinstr(void);
 
-
-EXPORT_SYMBOL(__backtrace);
-
 	/* networking */
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_from_user);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 32ab699..bd99bbb 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -437,7 +437,7 @@
 	printk("\n");
 	printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
 	__show_regs(regs);
-	__backtrace();
+	dump_stack();
 }
 
 ATOMIC_NOTIFIER_HEAD(thread_notify_head);
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index a673297..cd07b58 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -22,15 +22,10 @@
 #define mask	r7
 #define offset	r8
 
-ENTRY(__backtrace)
-		mov	r1, #0x10
-		mov	r0, fp
-
 ENTRY(c_backtrace)
 
 #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
 		mov	pc, lr
-ENDPROC(__backtrace)
 ENDPROC(c_backtrace)
 #else
 		stmfd	sp!, {r4 - r8, lr}	@ Save an extra register so we have a location...
@@ -107,7 +102,6 @@
 		mov	r1, frame
 		bl	printk
 no_frame:	ldmfd	sp!, {r4 - r8, pc}
-ENDPROC(__backtrace)
 ENDPROC(c_backtrace)
 		
 		.pushsection __ex_table,"a"
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 67ba2b1..3c2d47a 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1771,6 +1771,15 @@
 	  used to decrypt data and perform secure operations on the behalf of
 	  the kernel.
 
+config MSM_PIL_DSPS
+	tristate "DSPS Boot Support"
+	depends on MSM_PIL
+	help
+	  Support for booting and shutting down ARM7 DSPS processors.
+
+	  DSPS is a sensors offloading processor used for applications such
+	  as rotation detection, temperature, etc.
+
 config MSM_PIL_GSS
 	tristate "GSS (Coretx A5) Boot Support"
 	depends on MSM_PIL
@@ -1957,7 +1966,7 @@
 
 config MSM_WATCHDOG
 	bool "MSM Watchdog Support"
-	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM9615
+	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM9615 || ARCH_FSM9XXX
 	help
 		This enables the watchdog as is present on 8x60. Currently we use
 		core 0's watchdog, and reset the entire SoC if it times out. It does
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index e93993c..65da360 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -67,15 +67,12 @@
 obj-$(CONFIG_MSM_SECURE_IO) += scm-io.o
 obj-$(CONFIG_MSM_PIL) += peripheral-loader.o
 obj-$(CONFIG_MSM_PIL) += scm-pas.o
-ifdef CONFIG_MSM_PIL
-obj-$(CONFIG_ARCH_MSM8X60) += peripheral-reset.o
-obj-$(CONFIG_ARCH_MSM8960) += peripheral-reset-8960.o
-endif
 obj-$(CONFIG_MSM_PIL_QDSP6V3) += pil-q6v3.o
 obj-$(CONFIG_MSM_PIL_QDSP6V4) += pil-q6v4.o
 obj-$(CONFIG_MSM_PIL_RIVA) += pil-riva.o
 obj-$(CONFIG_MSM_PIL_TZAPPS) += pil-tzapps.o
 obj-$(CONFIG_MSM_PIL_MODEM) += pil-modem.o
+obj-$(CONFIG_MSM_PIL_DSPS) += pil-dsps.o
 obj-$(CONFIG_MSM_PIL_GSS) += pil-gss.o
 obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
 obj-$(CONFIG_ARCH_FSM9XXX) += sirc-fsm9xxx.o
@@ -223,7 +220,7 @@
 obj-$(CONFIG_MACH_MSM7X27_FFA) += board-msm7x27.o devices-msm7x27.o
 obj-$(CONFIG_ARCH_MSM7X27A) += clock-pcom-lookup.o devices-msm7x27a.o
 board-7627a-all-objs += board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o
-board-7627a-all-objs += board-msm7627a-display.o board-msm7627a-wlan.o
+board-7627a-all-objs += board-msm7627a-display.o board-msm7627a-wlan.o board-msm7627a-io.o
 obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-7627a-all.o
 obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-7627a-all.o
 obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-7627a-all.o
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index cbeac3f..051e165 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -36,6 +36,7 @@
 #include <mach/rpm-regulator.h>
 
 #include "acpuclock.h"
+#include "pm.h"
 
 /*
  * Source IDs.
@@ -377,10 +378,11 @@
 		},
 };
 
-static struct scalable *scalable;
 static struct l2_level *l2_freq_tbl;
 static struct acpu_level *acpu_freq_tbl;
 static int l2_freq_tbl_size;
+static struct scalable *scalable;
+#define SCALABLE_TO_CPU(sc) ((sc) - scalable)
 
 /* Instantaneous bandwidth requests in MB/s. */
 #define BW_MBPS(_bw) \
@@ -912,28 +914,37 @@
 		set_pri_clk_src(sc, tgt_s->pri_src_sel);
 	} else if (strt_s->src == HFPLL && tgt_s->src != HFPLL) {
 		/*
-		 * If responding to CPU_DEAD we must be running on another
-		 * CPU.  Therefore, we can't access the downed CPU's CP15
-		 * clock MUX registers from here and can't change clock sources.
-		 * Just turn off the PLL- since the CPU is down already, halting
-		 * its clock should be safe.
+		 * If responding to CPU_DEAD we must be running on another CPU.
+		 * Therefore, we can't access the downed CPU's clock MUX CP15
+		 * registers from here and can't change clock sources. If the
+		 * CPU is collapsed, however, it is still safe to turn off the
+		 * PLL without switching the MUX away from it.
 		 */
 		if (reason != SETRATE_HOTPLUG || sc == &scalable[L2]) {
 			set_sec_clk_src(sc, tgt_s->sec_src_sel);
 			set_pri_clk_src(sc, tgt_s->pri_src_sel);
+			hfpll_disable(sc, 0);
+		} else if (reason == SETRATE_HOTPLUG
+			   && msm_pm_verify_cpu_pc(SCALABLE_TO_CPU(sc))) {
+			hfpll_disable(sc, 0);
 		}
-		hfpll_disable(sc, 0);
 	} else if (strt_s->src != HFPLL && tgt_s->src == HFPLL) {
-		hfpll_set_rate(sc, tgt_s);
-		hfpll_enable(sc, 0);
 		/*
 		 * If responding to CPU_UP_PREPARE, we can't change CP15
 		 * registers for the CPU that's coming up since we're not
 		 * running on that CPU.  That's okay though, since the MUX
 		 * source was not changed on the way down, either.
 		 */
-		if (reason != SETRATE_HOTPLUG || sc == &scalable[L2])
+		if (reason != SETRATE_HOTPLUG || sc == &scalable[L2]) {
+			hfpll_set_rate(sc, tgt_s);
+			hfpll_enable(sc, 0);
 			set_pri_clk_src(sc, tgt_s->pri_src_sel);
+		} else if (reason == SETRATE_HOTPLUG
+			   && msm_pm_verify_cpu_pc(SCALABLE_TO_CPU(sc))) {
+			/* PLL was disabled during hot-unplug. Re-enable it. */
+			hfpll_set_rate(sc, tgt_s);
+			hfpll_enable(sc, 0);
+		}
 	} else {
 		if (reason != SETRATE_HOTPLUG || sc == &scalable[L2])
 			set_sec_clk_src(sc, tgt_s->sec_src_sel);
diff --git a/arch/arm/mach-msm/acpuclock-8x60.c b/arch/arm/mach-msm/acpuclock-8x60.c
index 7339a4c..787483b 100644
--- a/arch/arm/mach-msm/acpuclock-8x60.c
+++ b/arch/arm/mach-msm/acpuclock-8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -40,13 +40,12 @@
 #define COMPLEX_SLEW		7
 
 /* PLL calibration limits.
- * The PLL hardware is capable of 384MHz to 1536MHz. The L_VALs
- * used for calibration should respect these limits. */
+ * The PLL hardware has a minimum frequency of 384MHz.
+ * Calibration should respect this limit. */
 #define L_VAL_SCPLL_CAL_MIN	0x08 /* =  432 MHz with 27MHz source */
-#define L_VAL_SCPLL_CAL_MAX	0x1C /* = 1512 MHz with 27MHz source */
 
-#define MAX_VDD_SC		1250000 /* uV */
-#define MAX_VDD_MEM		1250000 /* uV */
+#define MAX_VDD_SC		1325000 /* uV */
+#define MAX_VDD_MEM		1325000 /* uV */
 #define MAX_VDD_DIG		1200000 /* uV */
 #define MAX_AXI			 310500 /* KHz */
 #define SCPLL_LOW_VDD_FMAX	 594000 /* KHz */
@@ -72,7 +71,7 @@
 #define SCPLL_STATUS_OFFSET		0x10
 #define SCPLL_CFG_OFFSET		0x1C
 #define SCPLL_FSM_CTL_EXT_OFFSET	0x24
-#define SCPLL_LUT_A_HW_MAX		(0x38 + ((L_VAL_SCPLL_CAL_MAX / 4) * 4))
+#define SCPLL_LUT_OFFSET(l_val)		(0x38 + (((l_val) / 4) * 4))
 
 /* Clock registers. */
 #define SPSS0_CLK_CTL_ADDR		(MSM_ACC0_BASE + 0x04)
@@ -218,6 +217,72 @@
 };
 
 /* SCPLL frequencies = 2 * 27 MHz * L_VAL */
+static struct clkctl_acpu_speed acpu_freq_tbl_slowest[] = {
+  { {1, 1},  192000,  ACPU_PLL_8, 3, 1, 0, 0,    L2(1),   800000, 0x03006000},
+  /* MAX_AXI row is used to source CPU cores and L2 from the AFAB clock. */
+  { {0, 0},  MAX_AXI, ACPU_AFAB,  1, 0, 0, 0,    L2(0),   825000, 0x03006000},
+  { {1, 1},  384000,  ACPU_PLL_8, 3, 0, 0, 0,    L2(1),   825000, 0x03006000},
+  { {1, 1},  432000,  ACPU_SCPLL, 0, 0, 1, 0x08, L2(1),   850000, 0x03006000},
+  { {1, 1},  486000,  ACPU_SCPLL, 0, 0, 1, 0x09, L2(2),   850000, 0x03006000},
+  { {1, 1},  540000,  ACPU_SCPLL, 0, 0, 1, 0x0A, L2(3),   875000, 0x03006000},
+  { {1, 1},  594000,  ACPU_SCPLL, 0, 0, 1, 0x0B, L2(4),   875000, 0x03006000},
+  { {1, 1},  648000,  ACPU_SCPLL, 0, 0, 1, 0x0C, L2(5),   900000, 0x03006000},
+  { {1, 1},  702000,  ACPU_SCPLL, 0, 0, 1, 0x0D, L2(6),   900000, 0x03006000},
+  { {1, 1},  756000,  ACPU_SCPLL, 0, 0, 1, 0x0E, L2(7),   925000, 0x03006000},
+  { {1, 1},  810000,  ACPU_SCPLL, 0, 0, 1, 0x0F, L2(8),   975000, 0x03006000},
+  { {1, 1},  864000,  ACPU_SCPLL, 0, 0, 1, 0x10, L2(9),   975000, 0x03006000},
+  { {1, 1},  918000,  ACPU_SCPLL, 0, 0, 1, 0x11, L2(10), 1000000, 0x03006000},
+  { {1, 1},  972000,  ACPU_SCPLL, 0, 0, 1, 0x12, L2(11), 1025000, 0x03006000},
+  { {1, 1}, 1026000,  ACPU_SCPLL, 0, 0, 1, 0x13, L2(12), 1025000, 0x03006000},
+  { {1, 1}, 1080000,  ACPU_SCPLL, 0, 0, 1, 0x14, L2(13), 1050000, 0x03006000},
+  { {1, 1}, 1134000,  ACPU_SCPLL, 0, 0, 1, 0x15, L2(14), 1075000, 0x03006000},
+  { {1, 1}, 1188000,  ACPU_SCPLL, 0, 0, 1, 0x16, L2(15), 1100000, 0x03006000},
+  { {1, 1}, 1242000,  ACPU_SCPLL, 0, 0, 1, 0x17, L2(16), 1125000, 0x03006000},
+  { {1, 1}, 1296000,  ACPU_SCPLL, 0, 0, 1, 0x18, L2(17), 1150000, 0x03006000},
+  { {1, 1}, 1350000,  ACPU_SCPLL, 0, 0, 1, 0x19, L2(18), 1175000, 0x03006000},
+  { {1, 1}, 1404000,  ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1200000, 0x03006000},
+  { {1, 1}, 1458000,  ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1225000, 0x03006000},
+  { {1, 1}, 1512000,  ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1250000, 0x03006000},
+  { {1, 1}, 1566000,  ACPU_SCPLL, 0, 0, 1, 0x1D, L2(19), 1275000, 0x03006000},
+  { {1, 1}, 1620000,  ACPU_SCPLL, 0, 0, 1, 0x1E, L2(19), 1300000, 0x03006000},
+  { {1, 1}, 1674000,  ACPU_SCPLL, 0, 0, 1, 0x1F, L2(19), 1325000, 0x03006000},
+  { {0, 0}, 0 },
+};
+
+/* SCPLL frequencies = 2 * 27 MHz * L_VAL */
+static struct clkctl_acpu_speed acpu_freq_tbl_slower[] = {
+  { {1, 1},  192000,  ACPU_PLL_8, 3, 1, 0, 0,    L2(1),   800000, 0x03006000},
+  /* MAX_AXI row is used to source CPU cores and L2 from the AFAB clock. */
+  { {0, 0},  MAX_AXI, ACPU_AFAB,  1, 0, 0, 0,    L2(0),   825000, 0x03006000},
+  { {1, 1},  384000,  ACPU_PLL_8, 3, 0, 0, 0,    L2(1),   825000, 0x03006000},
+  { {1, 1},  432000,  ACPU_SCPLL, 0, 0, 1, 0x08, L2(1),   850000, 0x03006000},
+  { {1, 1},  486000,  ACPU_SCPLL, 0, 0, 1, 0x09, L2(2),   850000, 0x03006000},
+  { {1, 1},  540000,  ACPU_SCPLL, 0, 0, 1, 0x0A, L2(3),   875000, 0x03006000},
+  { {1, 1},  594000,  ACPU_SCPLL, 0, 0, 1, 0x0B, L2(4),   875000, 0x03006000},
+  { {1, 1},  648000,  ACPU_SCPLL, 0, 0, 1, 0x0C, L2(5),   900000, 0x03006000},
+  { {1, 1},  702000,  ACPU_SCPLL, 0, 0, 1, 0x0D, L2(6),   900000, 0x03006000},
+  { {1, 1},  756000,  ACPU_SCPLL, 0, 0, 1, 0x0E, L2(7),   925000, 0x03006000},
+  { {1, 1},  810000,  ACPU_SCPLL, 0, 0, 1, 0x0F, L2(8),   975000, 0x03006000},
+  { {1, 1},  864000,  ACPU_SCPLL, 0, 0, 1, 0x10, L2(9),   975000, 0x03006000},
+  { {1, 1},  918000,  ACPU_SCPLL, 0, 0, 1, 0x11, L2(10), 1000000, 0x03006000},
+  { {1, 1},  972000,  ACPU_SCPLL, 0, 0, 1, 0x12, L2(11), 1025000, 0x03006000},
+  { {1, 1}, 1026000,  ACPU_SCPLL, 0, 0, 1, 0x13, L2(12), 1025000, 0x03006000},
+  { {1, 1}, 1080000,  ACPU_SCPLL, 0, 0, 1, 0x14, L2(13), 1050000, 0x03006000},
+  { {1, 1}, 1134000,  ACPU_SCPLL, 0, 0, 1, 0x15, L2(14), 1075000, 0x03006000},
+  { {1, 1}, 1188000,  ACPU_SCPLL, 0, 0, 1, 0x16, L2(15), 1100000, 0x03006000},
+  { {1, 1}, 1242000,  ACPU_SCPLL, 0, 0, 1, 0x17, L2(16), 1125000, 0x03006000},
+  { {1, 1}, 1296000,  ACPU_SCPLL, 0, 0, 1, 0x18, L2(17), 1150000, 0x03006000},
+  { {1, 1}, 1350000,  ACPU_SCPLL, 0, 0, 1, 0x19, L2(18), 1150000, 0x03006000},
+  { {1, 1}, 1404000,  ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1175000, 0x03006000},
+  { {1, 1}, 1458000,  ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1200000, 0x03006000},
+  { {1, 1}, 1512000,  ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1225000, 0x03006000},
+  { {1, 1}, 1566000,  ACPU_SCPLL, 0, 0, 1, 0x1D, L2(19), 1250000, 0x03006000},
+  { {1, 1}, 1620000,  ACPU_SCPLL, 0, 0, 1, 0x1E, L2(19), 1275000, 0x03006000},
+  { {1, 1}, 1674000,  ACPU_SCPLL, 0, 0, 1, 0x1F, L2(19), 1300000, 0x03006000},
+  { {0, 0}, 0 },
+};
+
+/* SCPLL frequencies = 2 * 27 MHz * L_VAL */
 static struct clkctl_acpu_speed acpu_freq_tbl_slow[] = {
   { {1, 1},  192000,  ACPU_PLL_8, 3, 1, 0, 0,    L2(1),   800000, 0x03006000},
   /* MAX_AXI row is used to source CPU cores and L2 from the AFAB clock. */
@@ -244,6 +309,9 @@
   { {1, 1}, 1404000,  ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1175000, 0x03006000},
   { {1, 1}, 1458000,  ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1200000, 0x03006000},
   { {1, 1}, 1512000,  ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1225000, 0x03006000},
+  { {1, 1}, 1566000,  ACPU_SCPLL, 0, 0, 1, 0x1D, L2(19), 1225000, 0x03006000},
+  { {1, 1}, 1620000,  ACPU_SCPLL, 0, 0, 1, 0x1E, L2(19), 1225000, 0x03006000},
+  { {1, 1}, 1674000,  ACPU_SCPLL, 0, 0, 1, 0x1F, L2(19), 1250000, 0x03006000},
   { {0, 0}, 0 },
 };
 
@@ -274,6 +342,9 @@
   { {1, 1}, 1404000,  ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1150000, 0x03006000},
   { {1, 1}, 1458000,  ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1150000, 0x03006000},
   { {1, 1}, 1512000,  ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1175000, 0x03006000},
+  { {1, 1}, 1566000,  ACPU_SCPLL, 0, 0, 1, 0x1D, L2(19), 1175000, 0x03006000},
+  { {1, 1}, 1620000,  ACPU_SCPLL, 0, 0, 1, 0x1E, L2(19), 1200000, 0x03006000},
+  { {1, 1}, 1674000,  ACPU_SCPLL, 0, 0, 1, 0x1F, L2(19), 1200000, 0x03006000},
   { {0, 0}, 0 },
 };
 
@@ -304,6 +375,9 @@
   { {1, 1}, 1404000,  ACPU_SCPLL, 0, 0, 1, 0x1A, L2(19), 1100000, 0x03006000},
   { {1, 1}, 1458000,  ACPU_SCPLL, 0, 0, 1, 0x1B, L2(19), 1100000, 0x03006000},
   { {1, 1}, 1512000,  ACPU_SCPLL, 0, 0, 1, 0x1C, L2(19), 1125000, 0x03006000},
+  { {1, 1}, 1566000,  ACPU_SCPLL, 0, 0, 1, 0x1D, L2(19), 1125000, 0x03006000},
+  { {1, 1}, 1620000,  ACPU_SCPLL, 0, 0, 1, 0x1E, L2(19), 1125000, 0x03006000},
+  { {1, 1}, 1674000,  ACPU_SCPLL, 0, 0, 1, 0x1F, L2(19), 1150000, 0x03006000},
   { {0, 0}, 0 },
 };
 
@@ -669,34 +743,29 @@
 	return rc;
 }
 
-static void __init scpll_init(int sc_pll)
+static void __init scpll_init(int pll, unsigned int max_l_val)
 {
 	uint32_t regval;
 
-	pr_debug("Initializing SCPLL%d\n", sc_pll);
+	pr_debug("Initializing SCPLL%d\n", pll);
 
 	/* Clear calibration LUT registers containing max frequency entry.
 	 * LUT registers are only writeable in debug mode. */
-	writel_relaxed(SCPLL_DEBUG_FULL,
-		       sc_pll_base[sc_pll] + SCPLL_DEBUG_OFFSET);
-	writel_relaxed(0x0, sc_pll_base[sc_pll] + SCPLL_LUT_A_HW_MAX);
-	writel_relaxed(SCPLL_DEBUG_NONE,
-		       sc_pll_base[sc_pll] + SCPLL_DEBUG_OFFSET);
+	writel_relaxed(SCPLL_DEBUG_FULL, sc_pll_base[pll] + SCPLL_DEBUG_OFFSET);
+	writel_relaxed(0x0, sc_pll_base[pll] + SCPLL_LUT_OFFSET(max_l_val));
+	writel_relaxed(SCPLL_DEBUG_NONE, sc_pll_base[pll] + SCPLL_DEBUG_OFFSET);
 
 	/* Power-up SCPLL into standby mode. */
-	writel_relaxed(SCPLL_STANDBY, sc_pll_base[sc_pll] + SCPLL_CTL_OFFSET);
+	writel_relaxed(SCPLL_STANDBY, sc_pll_base[pll] + SCPLL_CTL_OFFSET);
 	mb();
 	udelay(10);
 
-	/* Calibrate the SCPLL to the maximum range supported by the h/w. We
-	 * might not use the full range of calibrated frequencies, but this
-	 * simplifies changes required for future increases in max CPU freq.
-	 */
-	regval = (L_VAL_SCPLL_CAL_MAX << 24) | (L_VAL_SCPLL_CAL_MIN << 16);
-	writel_relaxed(regval, sc_pll_base[sc_pll] + SCPLL_CAL_OFFSET);
+	/* Calibrate the SCPLL for the frequency range needed. */
+	regval = (max_l_val << 24) | (L_VAL_SCPLL_CAL_MIN << 16);
+	writel_relaxed(regval, sc_pll_base[pll] + SCPLL_CAL_OFFSET);
 
 	/* Start calibration */
-	writel_relaxed(SCPLL_FULL_CAL, sc_pll_base[sc_pll] + SCPLL_CTL_OFFSET);
+	writel_relaxed(SCPLL_FULL_CAL, sc_pll_base[pll] + SCPLL_CTL_OFFSET);
 
 	/* Wait for proof that calibration has started before checking the
 	 * 'calibration done' bit in the status register. Waiting for the
@@ -704,15 +773,15 @@
 	 * This is required since the 'calibration done' bit takes time to
 	 * transition from 'done' to 'not done' when starting a calibration.
 	 */
-	while (readl_relaxed(sc_pll_base[sc_pll] + SCPLL_LUT_A_HW_MAX) == 0)
+	while (!readl_relaxed(sc_pll_base[pll] + SCPLL_LUT_OFFSET(max_l_val)))
 		cpu_relax();
 
 	/* Wait for calibration to complete. */
-	while (readl_relaxed(sc_pll_base[sc_pll] + SCPLL_STATUS_OFFSET) & 0x2)
+	while (readl_relaxed(sc_pll_base[pll] + SCPLL_STATUS_OFFSET) & 0x2)
 		cpu_relax();
 
 	/* Power-down SCPLL. */
-	scpll_disable(sc_pll);
+	scpll_disable(pll);
 }
 
 /* Force ACPU core and L2 cache clocks to rates that don't require SCPLLs. */
@@ -859,7 +928,7 @@
 	.notifier_call = acpuclock_cpu_callback,
 };
 
-static unsigned int __init select_freq_plan(void)
+static __init struct clkctl_acpu_speed *select_freq_plan(void)
 {
 	uint32_t pte_efuse, speed_bin, pvs, max_khz;
 	struct clkctl_acpu_speed *f;
@@ -870,12 +939,41 @@
 	if (speed_bin == 0xF)
 		speed_bin = (pte_efuse >> 4) & 0xF;
 
-	if (speed_bin == 0x1) {
-		max_khz = 1512000;
-		pvs = (pte_efuse >> 10) & 0x7;
-		if (pvs == 0x7)
-			pvs = (pte_efuse >> 13) & 0x7;
+	pvs = (pte_efuse >> 10) & 0x7;
+	if (pvs == 0x7)
+		pvs = (pte_efuse >> 13) & 0x7;
 
+	if (speed_bin == 0x2) {
+		max_khz = 1674000;
+		switch (pvs) {
+		case 0x7:
+		case 0x5:
+			acpu_freq_tbl = acpu_freq_tbl_slowest;
+			pr_info("ACPU PVS: Slowest\n");
+			break;
+		case 0x4:
+			acpu_freq_tbl = acpu_freq_tbl_slower;
+			pr_info("ACPU PVS: Slower\n");
+			break;
+		case 0x0:
+			acpu_freq_tbl = acpu_freq_tbl_slow;
+			pr_info("ACPU PVS: Slow\n");
+			break;
+		case 0x1:
+			acpu_freq_tbl = acpu_freq_tbl_nom;
+			pr_info("ACPU PVS: Nominal\n");
+			break;
+		case 0x3:
+			acpu_freq_tbl = acpu_freq_tbl_fast;
+			pr_info("ACPU PVS: Fast\n");
+			break;
+		default:
+			acpu_freq_tbl = acpu_freq_tbl_slowest;
+			pr_warn("ACPU PVS: Unknown. Defaulting to slowest.\n");
+			break;
+		}
+	} else if (speed_bin == 0x1) {
+		max_khz = 1512000;
 		switch (pvs) {
 		case 0x0:
 		case 0x7:
@@ -910,7 +1008,7 @@
 	f--;
 	pr_info("Max ACPU freq: %u KHz\n", f->acpuclk_khz);
 
-	return f->acpuclk_khz;
+	return f;
 }
 
 static struct acpuclk_data acpuclk_8x60_data = {
@@ -922,25 +1020,25 @@
 
 static int __init acpuclk_8x60_init(struct acpuclk_soc_data *soc_data)
 {
-	unsigned int max_cpu_khz;
+	struct clkctl_acpu_speed *max_freq;
 	int cpu;
 
 	mutex_init(&drv_state.lock);
 	spin_lock_init(&drv_state.l2_lock);
 
 	/* Configure hardware. */
-	max_cpu_khz = select_freq_plan();
+	max_freq = select_freq_plan();
 	unselect_scplls();
 	scpll_set_refs();
 	for_each_possible_cpu(cpu)
-		scpll_init(cpu);
-	scpll_init(L2);
+		scpll_init(cpu, max_freq->l_val);
+	scpll_init(L2, max_freq->l2_level->l_val);
 	regulator_init();
 	bus_init();
 
 	/* Improve boot time by ramping up CPUs immediately. */
 	for_each_online_cpu(cpu)
-		acpuclk_8x60_set_rate(cpu, max_cpu_khz, SETRATE_INIT);
+		acpuclk_8x60_set_rate(cpu, max_freq->acpuclk_khz, SETRATE_INIT);
 
 	acpuclk_register(&acpuclk_8x60_data);
 	cpufreq_table_init();
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 157c939..9080e60 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -461,6 +461,7 @@
 	.sensor_platform_info = &sensor_board_info_imx074,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 	.actuator_info = &imx074_actuator_info
 };
 static struct msm_camera_csi_lane_params imx091_csi_lane_params = {
@@ -495,6 +496,7 @@
 	.sensor_platform_info = &sensor_board_info_imx091,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 };
 
 static struct camera_vreg_t apq_8064_mt9m114_vreg[] = {
@@ -529,6 +531,7 @@
 	.sensor_platform_info = &sensor_board_info_mt9m114,
 	.csi_if = 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = YUV_SENSOR,
 };
 
 static struct msm_camera_sensor_flash_data flash_ov2720 = {
@@ -556,6 +559,7 @@
 	.sensor_platform_info = &sensor_board_info_ov2720,
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 };
 
 void __init apq8064_init_cam(void)
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index bf82e40..2f94069 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -53,6 +53,13 @@
 	.pull = GPIOMUX_PULL_UP,
 };
 
+/* Chip selects for EPM SPI clients */
+static struct gpiomux_setting gpio_epm_spi_cs_config = {
+	.func = GPIOMUX_FUNC_3,
+	.drv = GPIOMUX_DRV_12MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
 struct msm_gpiomux_config apq8064_ethernet_configs[] = {
 	{
 		.gpio = 43,
@@ -371,7 +378,7 @@
 	{
 		.gpio      = 32,		/* EPM CS */
 		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+			[GPIOMUX_SUSPENDED] = &gpio_epm_spi_cs_config,
 		},
 	},
 	{
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index df28390..f915657 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -142,8 +142,6 @@
 /* Initial PM8XXX MPP configurations */
 static struct pm8xxx_mpp_init pm8xxx_mpps[] __initdata = {
 	PM8921_MPP_INIT(3, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
-	/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
-	PM8921_MPP_INIT(7, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
 	PM8921_MPP_INIT(8, D_OUTPUT, PM8921_MPP_DIG_LEVEL_S4, DOUT_CTRL_LOW),
 	/*MPP9 is used to detect docking station connection/removal on Liquid*/
 	PM8921_MPP_INIT(9, D_INPUT, PM8921_MPP_DIG_LEVEL_S4, DIN_TO_INT),
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 025f065..24df393 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -229,6 +229,7 @@
 };
 VREG_CONSUMERS(EXT_5V) = {
 	REGULATOR_SUPPLY("ext_5v",		NULL),
+	REGULATOR_SUPPLY("ext_ddr3",		NULL),
 	REGULATOR_SUPPLY("vbus",		"msm_ehci_host.0"),
 };
 VREG_CONSUMERS(EXT_MPP8) = {
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index b062dde..8212808 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -16,6 +16,7 @@
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/i2c/smb349.h>
+#include <linux/i2c/sx150x.h>
 #include <linux/slimbus/slimbus.h>
 #include <linux/mfd/wcd9xxx/core.h>
 #include <linux/mfd/wcd9xxx/pdata.h>
@@ -30,6 +31,7 @@
 #include <linux/cyttsp.h>
 #include <linux/i2c/isa1200.h>
 #include <linux/gpio_keys.h>
+#include <linux/epm_adc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -74,7 +76,7 @@
 #include "devices-msm8x60.h"
 
 #define MSM_PMEM_ADSP_SIZE         0x7800000
-#define MSM_PMEM_AUDIO_SIZE        0x2B4000
+#define MSM_PMEM_AUDIO_SIZE        0x4CF000
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 #define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
 #else
@@ -82,7 +84,7 @@
 #endif
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-#define MSM_PMEM_KERNEL_EBI1_SIZE  0x280000
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0x65000
 #define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
 #define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
 #define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
@@ -630,6 +632,60 @@
 	},
 };
 
+struct sx150x_platform_data apq8064_sx150x_data[] = {
+	[SX150X_EPM] = {
+		.gpio_base	= GPIO_EPM_EXPANDER_BASE,
+		.oscio_is_gpo	= false,
+		.io_pullup_ena	= 0x0,
+		.io_pulldn_ena	= 0x0,
+		.io_open_drain_ena = 0x0,
+		.io_polarity	= 0,
+		.irq_summary	= -1,
+	},
+};
+
+static struct epm_chan_properties ads_adc_channel_data[] = {
+	{10, 100}, {500, 50}, {1, 1}, {1, 1},
+	{20, 50}, {10, 100}, {1, 1}, {1, 1},
+	{10, 100}, {10, 100}, {100, 100}, {200, 100},
+	{100, 50}, {2000, 50}, {1000, 50}, {200, 50},
+	{200, 100}, {1, 1}, {20, 50}, {500, 50},
+	{50, 50}, {200, 100}, {500, 100}, {20, 50},
+	{200, 50}, {2000, 100}, {1000, 50}, {100, 50},
+	{200, 100}, {500, 50}, {1000, 100}, {200, 50},
+	{1000, 50}, {50, 50}, {100, 50}, {100, 50},
+	{1, 1}, {1, 1}, {20, 100}, {20, 50},
+	{500, 100}, {1000, 100}, {100, 50}, {1000, 50},
+	{100, 50}, {1000, 100}, {100, 50}, {100, 50},
+};
+
+static struct epm_adc_platform_data epm_adc_pdata = {
+	.channel		= ads_adc_channel_data,
+	.bus_id	= 0x0,
+	.epm_i2c_board_info = {
+		.type	= "sx1509q",
+		.addr = 0x3e,
+		.platform_data = &apq8064_sx150x_data[SX150X_EPM],
+	},
+	.gpio_expander_base_addr = GPIO_EPM_EXPANDER_BASE,
+};
+
+static struct platform_device epm_adc_device = {
+	.name   = "epm_adc",
+	.id = -1,
+	.dev = {
+		.platform_data = &epm_adc_pdata,
+	},
+};
+
+static void __init apq8064_epm_adc_init(void)
+{
+	epm_adc_pdata.num_channels = 32;
+	epm_adc_pdata.num_adc = 2;
+	epm_adc_pdata.chan_per_adc = 16;
+	epm_adc_pdata.chan_per_mux = 8;
+};
+
 #define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_IRQS)
 
 /* Micbias setting is based on 8660 CDP/MTP/FLUID requirement
@@ -1803,6 +1859,7 @@
 	&msm_bus_8064_sys_fpb,
 	&msm_bus_8064_cpss_fpb,
 	&apq8064_msm_device_vidc,
+	&msm_pil_dsps,
 	&msm_8960_riva,
 	&msm_8960_q6_lpass,
 	&msm_gss,
@@ -1812,6 +1869,7 @@
 	&apq8064_cpu_idle_device,
 	&apq8064_msm_gov_device,
 	&apq8064_device_cache_erp,
+	&epm_adc_device,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
@@ -1851,6 +1909,13 @@
 		.chip_select            = 2,
 		.mode                   = SPI_MODE_0,
 	},
+	{
+		.modalias		= "epm_adc",
+		.max_speed_hz		= 1100000,
+		.bus_num		= 0,
+		.chip_select		= 3,
+		.mode			= SPI_MODE_0,
+	},
 };
 
 static struct slim_boardinfo apq8064_slim_devices[] = {
@@ -1896,6 +1961,8 @@
 	apq8064_i2c_qup_gsbi1_pdata.use_gsbi_shared_mode = 1;
 	apq8064_device_qup_i2c_gsbi3.dev.platform_data =
 					&apq8064_i2c_qup_gsbi3_pdata;
+	apq8064_device_qup_i2c_gsbi1.dev.platform_data =
+					&apq8064_i2c_qup_gsbi1_pdata;
 	apq8064_device_qup_i2c_gsbi4.dev.platform_data =
 					&apq8064_i2c_qup_gsbi4_pdata;
 }
@@ -2133,6 +2200,20 @@
 #endif
 }
 
+static void enable_ddr3_regulator(void)
+{
+	static struct regulator *ext_ddr3;
+
+	/* Use MPP7 output state as a flag for PCDDR3 presence. */
+	if (gpio_get_value_cansleep(PM8921_MPP_PM_TO_SYS(7)) > 0) {
+		ext_ddr3 = regulator_get(NULL, "ext_ddr3");
+		if (IS_ERR(ext_ddr3) || ext_ddr3 == NULL)
+			pr_err("Could not get MPP7 regulator\n");
+		else
+			regulator_enable(ext_ddr3);
+	}
+}
+
 static void __init apq8064_common_init(void)
 {
 	if (socinfo_init() < 0)
@@ -2153,10 +2234,15 @@
 	apq8064_init_pmic();
 	if (machine_is_apq8064_liquid())
 		msm_otg_pdata.mhl_enable = true;
+
+	msm_otg_pdata.swfi_latency =
+		msm_rpmrs_levels[0].latency_us + 1;
+
 	apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
 	apq8064_ehci_host_init();
 	apq8064_init_buses();
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	enable_ddr3_regulator();
 	if (machine_is_apq8064_mtp()) {
 		apq8064_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
 		device_initialize(&apq8064_device_hsic_host.dev);
@@ -2180,6 +2266,7 @@
 	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
 				msm_pm_data);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	apq8064_epm_adc_init();
 }
 
 static void __init apq8064_allocate_memory_regions(void)
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 315e8fc..92e88aa72 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -446,6 +446,7 @@
 	.sensor_platform_info = &sensor_board_info_imx074,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 	.actuator_info = &imx074_actuator_info
 };
 
@@ -480,6 +481,7 @@
 	.sensor_platform_info = &sensor_board_info_mt9m114,
 	.csi_if = 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = YUV_SENSOR,
 };
 
 static struct msm_camera_sensor_flash_data flash_ov2720 = {
@@ -506,6 +508,7 @@
 	.sensor_platform_info = &sensor_board_info_ov2720,
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 };
 
 static struct camera_vreg_t msm_8930_s5k3l1yx_vreg[] = {
@@ -539,6 +542,7 @@
 	.sensor_platform_info = &sensor_board_info_s5k3l1yx,
 	.csi_if               = 1,
 	.camera_type          = BACK_CAMERA_2D,
+	.sensor_type          = BAYER_SENSOR,
 };
 
 void __init msm8930_init_cam(void)
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index 77d9c5f..cd201ef 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -611,7 +611,11 @@
 };
 #endif
 
-#ifdef MSM8930_PHASE_2
+static struct gpiomux_setting haptics_active_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_UP,
+};
 static struct gpiomux_setting haptics_suspend_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_8MA,
@@ -622,17 +626,18 @@
 	{
 		.gpio = 77,
 		.settings = {
+			[GPIOMUX_ACTIVE] = &haptics_active_cfg,
 			[GPIOMUX_SUSPENDED] = &haptics_suspend_cfg,
 		},
 	},
 	{
 		.gpio = 78,
 		.settings = {
+			[GPIOMUX_ACTIVE] = &haptics_active_cfg,
 			[GPIOMUX_SUSPENDED] = &haptics_suspend_cfg,
 		},
 	},
 };
-#endif
 
 int __init msm8930_init_gpiomux(void)
 {
@@ -679,11 +684,10 @@
 		msm_gpiomux_install(mdm_configs,
 			ARRAY_SIZE(mdm_configs));
 
-#ifdef MSM8930_PHASE_2
-	if (machine_is_msm8930_mtp() || machine_is_msm8930_fluid())
+	if (machine_is_msm8930_cdp() || machine_is_msm8930_mtp()
+		|| machine_is_msm8930_fluid())
 		msm_gpiomux_install(msm8930_haptics_configs,
 			ARRAY_SIZE(msm8930_haptics_configs));
-#endif
 
 #ifdef CONFIG_USB_EHCI_MSM_HSIC
 	if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1) &&
diff --git a/arch/arm/mach-msm/board-8930-gpu.c b/arch/arm/mach-msm/board-8930-gpu.c
index a5157038..7c8c64f 100644
--- a/arch/arm/mach-msm/board-8930-gpu.c
+++ b/arch/arm/mach-msm/board-8930-gpu.c
@@ -53,7 +53,7 @@
 		.src = MSM_BUS_MASTER_GRAPHICS_3D,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
 		.ab = 0,
-		.ib = KGSL_CONVERT_TO_MBPS(3200),
+		.ib = KGSL_CONVERT_TO_MBPS(4264),
 	},
 };
 
@@ -115,17 +115,17 @@
 static struct kgsl_device_platform_data kgsl_3d0_pdata = {
 	.pwrlevel = {
 		{
-			.gpu_freq = 200000000,
+			.gpu_freq = 450000000,
 			.bus_freq = 3,
 			.io_fraction = 0,
 		},
 		{
-			.gpu_freq = 200000000,
+			.gpu_freq = 320000000,
 			.bus_freq = 2,
 			.io_fraction = 33,
 		},
 		{
-			.gpu_freq = 200000000,
+			.gpu_freq = 192000000,
 			.bus_freq = 1,
 			.io_fraction = 100,
 		},
@@ -137,8 +137,8 @@
 	.init_level = 0,
 	.num_levels = 4,
 	.set_grp_async = NULL,
-	.idle_timeout = 0x1FFFFFFF,
-	.nap_allowed = false,
+	.idle_timeout = HZ/12,
+	.nap_allowed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table = &grp3d_bus_scale_pdata,
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 1ca1902..6f94f37 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -93,6 +93,8 @@
 	PM8XXX_GPIO_INPUT(8, PM_GPIO_PULL_UP_30),
 	PM8XXX_GPIO_INPUT(10, PM_GPIO_PULL_UP_30),
 	PM8XXX_GPIO_INPUT(11, PM_GPIO_PULL_UP_30),
+	/* haptics gpio */
+	PM8XXX_GPIO_OUTPUT_FUNC(7, 0, PM_GPIO_FUNC_1),
 };
 
 /* Initial pm8038 MPP configurations */
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index e8500dc..f760e7b 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -84,6 +84,7 @@
 	REGULATOR_SUPPLY("VDDIO_CDC",		"sitar-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_TX",		"sitar-slim"),
 	REGULATOR_SUPPLY("CDC_VDDA_RX",		"sitar-slim"),
+	REGULATOR_SUPPLY("vddp",		"0-0048"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8038_l12",		NULL),
@@ -179,7 +180,7 @@
 	REGULATOR_SUPPLY("8038_lvs2",		NULL),
 	REGULATOR_SUPPLY("vcc_i2c",		"3-004a"),
 	REGULATOR_SUPPLY("vcc_i2c",		"3-0024"),
-	REGULATOR_SUPPLY("vddp",		"12-0048"),
+	REGULATOR_SUPPLY("vcc_i2c",		"0-0048"),
 };
 VREG_CONSUMERS(EXT_5V) = {
 	REGULATOR_SUPPLY("ext_5v",		NULL),
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index 26211bf..83fb5fd 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -245,6 +245,7 @@
 	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
 #else
 	.wpswitch_gpio	= 66,
+	.wpswitch_polarity = 1,
 #endif
 #endif
 	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 59651a7..dc6c135 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1218,127 +1218,25 @@
 #/* TODO: Remove this once PM8038 physically becomes
  * available.
  */
-#ifndef MSM8930_PHASE_2
-#define PM_HAP_EN_GPIO		PM8921_GPIO_PM_TO_SYS(33)
-#define PM_HAP_LEN_GPIO		PM8921_GPIO_PM_TO_SYS(20)
-#else
 #define ISA1200_HAP_EN_GPIO	77
 #define ISA1200_HAP_LEN_GPIO	78
 #define ISA1200_HAP_CLK		PM8038_GPIO_PM_TO_SYS(7)
-#endif
-
-#ifndef MSM8930_PHASE_2
-static struct msm_xo_voter *xo_handle_d1;
-#endif
 
 static int isa1200_power(int on)
 {
-#ifndef MSM8930_PHASE_2
-	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;
-#else
 	gpio_set_value_cansleep(ISA1200_HAP_CLK, !!on);
 
 	return 0;
-#endif
-
 }
 
 static int isa1200_dev_setup(bool enable)
 {
 	int rc = 0;
 
-#ifndef MSM8930_PHASE_2
-	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;
-#else
-	struct pm_gpio hap_clk_gpio_config = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.out_strength   = PM_GPIO_STRENGTH_HIGH,
-		.function       = PM_GPIO_FUNC_1,
-		.inv_int_pol    = 0,
-		.vin_sel        = PM_GPIO_VIN_S4,
-		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-		.output_value   = 0,
-	};
-
-	rc = pm8xxx_gpio_config(ISA1200_HAP_CLK, &hap_clk_gpio_config);
+	rc = pm8xxx_aux_clk_control(CLK_MP3_1, XO_DIV_1, enable);
 	if (rc) {
-		pr_err("%s: pm8038 gpio %d config failed(%d)\n",
-				__func__, ISA1200_HAP_CLK, rc);
+		pr_err("%s: unable to write aux clock register(%d)\n",
+			__func__, rc);
 		return rc;
 	}
 
@@ -1363,38 +1261,29 @@
 fail_gpio_req:
 	return rc;
 
-#endif
 }
 
 static struct isa1200_regulator isa1200_reg_data[] = {
-#ifndef MSM8930_PHASE_2
-	{
-		.name = "vcc_i2c",
-		.min_uV = ISA_I2C_VTG_MIN_UV,
-		.max_uV = ISA_I2C_VTG_MAX_UV,
-		.load_uA = ISA_I2C_CURR_UA,
-	},
-#else
 	{
 		.name = "vddp",
 		.min_uV = ISA_I2C_VTG_MIN_UV,
 		.max_uV = ISA_I2C_VTG_MAX_UV,
 		.load_uA = ISA_I2C_CURR_UA,
 	},
-#endif
+	{
+		.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,
-#ifndef MSM8930_PHASE_2
-	.hap_en_gpio = PM_HAP_EN_GPIO,
-	.hap_len_gpio = PM_HAP_LEN_GPIO,
-#else
 	.hap_en_gpio = ISA1200_HAP_EN_GPIO,
 	.hap_len_gpio = ISA1200_HAP_LEN_GPIO,
-#endif
 	.max_timeout = 15000,
 	.mode_ctrl = PWM_GEN_MODE,
 	.pwm_fd = {
@@ -2099,21 +1988,12 @@
 		ARRAY_SIZE(isl_charger_i2c_info),
 	},
 #endif /* CONFIG_ISL9519_CHARGER */
-#ifndef MSM8930_PHASE_2
 	{
-		I2C_LIQUID,
-		MSM_8930_GSBI10_QUP_I2C_BUS_ID,
+		I2C_SURF | I2C_FFA | I2C_FLUID,
+		MSM_8930_GSBI9_QUP_I2C_BUS_ID,
 		msm_isa1200_board_info,
 		ARRAY_SIZE(msm_isa1200_board_info),
 	},
-#else
-	{
-		I2C_FFA | I2C_FLUID,
-		MSM_8930_GSBI10_QUP_I2C_BUS_ID,
-		msm_isa1200_board_info,
-		ARRAY_SIZE(msm_isa1200_board_info),
-	},
-#endif
 	{
 		I2C_SURF,
 		MSM_8930_GSBI3_QUP_I2C_BUS_ID,
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index 45fe40f..a8fad72 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -133,6 +133,7 @@
 		(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_GSBI4_QUP_I2C_BUS_ID 4
+#define MSM_8930_GSBI9_QUP_I2C_BUS_ID 0
 #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
index d51a6d3..c2a378f 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -517,6 +517,7 @@
 	.sensor_platform_info = &sensor_board_info_imx074,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 	.actuator_info = &imx074_actuator_info
 };
 
@@ -551,6 +552,7 @@
 	.sensor_platform_info = &sensor_board_info_mt9m114,
 	.csi_if = 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = YUV_SENSOR,
 };
 
 static struct msm_camera_sensor_flash_data flash_ov2720 = {
@@ -577,6 +579,7 @@
 	.sensor_platform_info = &sensor_board_info_ov2720,
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 };
 
 static struct camera_vreg_t msm_8960_s5k3l1yx_vreg[] = {
@@ -610,6 +613,7 @@
 	.sensor_platform_info = &sensor_board_info_s5k3l1yx,
 	.csi_if               = 1,
 	.camera_type          = BACK_CAMERA_2D,
+	.sensor_type          = BAYER_SENSOR,
 };
 
 static struct msm_camera_csi_lane_params imx091_csi_lane_params = {
@@ -643,6 +647,7 @@
 	.sensor_platform_info = &sensor_board_info_imx091,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 };
 
 static struct pm8xxx_mpp_config_data privacy_light_on_config = {
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index 2a29ad0..e28b4ea 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -162,8 +162,11 @@
 
 	if (!strncmp(name, HDMI_PANEL_NAME,
 			strnlen(HDMI_PANEL_NAME,
-				PANEL_NAME_MAX_LEN)))
+				PANEL_NAME_MAX_LEN))) {
+		if (hdmi_is_primary)
+			set_mdp_clocks_for_wuxga();
 		return 0;
+	}
 
 	if (!strncmp(name, TVOUT_PANEL_NAME,
 			strnlen(TVOUT_PANEL_NAME,
@@ -575,43 +578,6 @@
 	},
 };
 
-#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,
@@ -677,7 +643,6 @@
 		mdp_1080p_vectors,
 	},
 };
-#endif
 
 static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
 	mdp_bus_scale_usecases,
@@ -711,30 +676,6 @@
 	.cont_splash_enabled = 0x01,
 };
 
-/**
- * Set MDP clocks to high frequency to avoid DSI underflow
- * when using high resolution 1200x1920 WUXGA panels
- */
-static void set_mdp_clocks_for_wuxga(void)
-{
-	int i;
-
-	mdp_ui_vectors[0].ab = 2000000000;
-	mdp_ui_vectors[0].ib = 2000000000;
-	mdp_vga_vectors[0].ab = 2000000000;
-	mdp_vga_vectors[0].ib = 2000000000;
-	mdp_720p_vectors[0].ab = 2000000000;
-	mdp_720p_vectors[0].ib = 2000000000;
-	mdp_1080p_vectors[0].ab = 2000000000;
-	mdp_1080p_vectors[0].ib = 2000000000;
-
-	mdp_pdata.mdp_core_clk_rate = 200000000;
-
-	for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
-		mdp_core_clk_rate_table[i] = 200000000;
-
-}
-
 void __init msm8960_mdp_writeback(struct memtype_reserve* reserve_table)
 {
 	mdp_pdata.ov0_wb_size = MSM_FB_OVERLAY0_WRITEBACK_SIZE;
@@ -1156,6 +1097,34 @@
 			size, addr, __pa(addr));
 }
 
+/**
+ * Set MDP clocks to high frequency to avoid DSI underflow
+ * when using high resolution 1200x1920 WUXGA panels
+ */
+static void set_mdp_clocks_for_wuxga(void)
+{
+	int i;
+
+	mdp_ui_vectors[0].ab = 2000000000;
+	mdp_ui_vectors[0].ib = 2000000000;
+	mdp_vga_vectors[0].ab = 2000000000;
+	mdp_vga_vectors[0].ib = 2000000000;
+	mdp_720p_vectors[0].ab = 2000000000;
+	mdp_720p_vectors[0].ib = 2000000000;
+	mdp_1080p_vectors[0].ab = 2000000000;
+	mdp_1080p_vectors[0].ib = 2000000000;
+
+	mdp_pdata.mdp_core_clk_rate = 200000000;
+
+	for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
+		mdp_core_clk_rate_table[i] = 200000000;
+
+	if (hdmi_is_primary) {
+		dtv_bus_def_vectors[0].ab = 2000000000;
+		dtv_bus_def_vectors[0].ib = 2000000000;
+	}
+}
+
 void __init msm8960_set_display_params(char *prim_panel, char *ext_panel)
 {
 	if (strnlen(prim_panel, PANEL_NAME_MAX_LEN)) {
@@ -1170,6 +1139,13 @@
 			pr_debug("HDMI is the primary display by"
 				" boot parameter\n");
 			hdmi_is_primary = 1;
+			set_mdp_clocks_for_wuxga();
+		}
+		if (!strncmp((char *)msm_fb_pdata.prim_panel_name,
+				MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME,
+				strnlen(MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME,
+					PANEL_NAME_MAX_LEN))) {
+			set_mdp_clocks_for_wuxga();
 		}
 	}
 	if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index e8df203..4ef7d6e 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -130,20 +130,27 @@
 #endif
 
 #define MSM_PMEM_ADSP_SIZE         0x7800000
-#define MSM_PMEM_AUDIO_SIZE        0x2B4000
+#define MSM_PMEM_AUDIO_SIZE        0x4CF000
 #define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
 #define MSM_LIQUID_PMEM_SIZE 0x4000000 /* 64 Mbytes */
 #define MSM_HDMI_PRIM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-#define MSM_PMEM_KERNEL_EBI1_SIZE  0x280000
-#define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0x65000
+#ifdef CONFIG_MSM_IOMMU
+#define MSM_ION_MM_SIZE            0x3800000
+#define MSM_ION_SF_SIZE            0x0
+#define MSM_ION_HEAP_NUM	7
+#else
+#define MSM_ION_MM_SIZE            MSM_PMEM_ADSP_SIZE
+#define MSM_ION_SF_SIZE            MSM_PMEM_SIZE
+#define MSM_ION_HEAP_NUM	8
+#endif
 #define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
-#define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
 #define MSM_ION_QSECOM_SIZE	0x600000 /* (6MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
 #define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
-#define MSM_ION_HEAP_NUM	8
+
 #define MSM_LIQUID_ION_MM_SIZE (MSM_ION_MM_SIZE + 0x600000)
 #define MSM_LIQUID_ION_SF_SIZE MSM_LIQUID_PMEM_SIZE
 #define MSM_HDMI_PRIM_ION_SF_SIZE MSM_HDMI_PRIM_PMEM_SIZE
@@ -417,6 +424,7 @@
 			.memory_type = ION_EBI_TYPE,
 			.extra_data = (void *) &cp_mfc_ion_pdata,
 		},
+#ifndef CONFIG_MSM_IOMMU
 		{
 			.id	= ION_SF_HEAP_ID,
 			.type	= ION_HEAP_TYPE_CARVEOUT,
@@ -425,6 +433,7 @@
 			.memory_type = ION_EBI_TYPE,
 			.extra_data = (void *) &co_ion_pdata,
 		},
+#endif
 		{
 			.id	= ION_IOMMU_HEAP_ID,
 			.type	= ION_HEAP_TYPE_IOMMU,
@@ -2267,6 +2276,7 @@
 	&msm_8960_q6_mss_sw,
 	&msm_8960_riva,
 	&msm_pil_tzapps,
+	&msm_pil_dsps,
 	&msm8960_device_otg,
 	&msm8960_device_gadget_peripheral,
 	&msm_device_hsusb_host,
diff --git a/arch/arm/mach-msm/board-copper-regulator.c b/arch/arm/mach-msm/board-copper-regulator.c
index 89878ce..9409936 100644
--- a/arch/arm/mach-msm/board-copper-regulator.c
+++ b/arch/arm/mach-msm/board-copper-regulator.c
@@ -138,6 +138,18 @@
 VREG_CONSUMERS(LVS3) = {
 	REGULATOR_SUPPLY("8941_lvs3",		NULL),
 };
+VREG_CONSUMERS(K0) = {
+	REGULATOR_SUPPLY("krait0",		NULL),
+};
+VREG_CONSUMERS(K1) = {
+	REGULATOR_SUPPLY("krait1",		NULL),
+};
+VREG_CONSUMERS(K2) = {
+	REGULATOR_SUPPLY("krait2",		NULL),
+};
+VREG_CONSUMERS(K3) = {
+	REGULATOR_SUPPLY("krait3",		NULL),
+};
 
 #define PM8X41_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
 			 _always_on, _supply_regulator, _hpm_min, _system_uA)  \
@@ -189,6 +201,14 @@
 	PM8X41_VREG_INIT(_id, _name, 0, 0, 0, REGULATOR_CHANGE_STATUS, \
 		 _always_on, _supply_regulator, 0, 0)
 
+#define KRAIT_PWR(_id, _name, _always_on, _min_uV, _max_uV, \
+		_supply_regulator, _hpm_min, _system_uA) \
+	PM8X41_VREG_INIT(_id, _name, _min_uV, _max_uV, REGULATOR_MODE_NORMAL \
+		| REGULATOR_MODE_IDLE, REGULATOR_CHANGE_VOLTAGE | \
+		REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
+		REGULATOR_CHANGE_DRMS, _always_on, \
+		_supply_regulator, _hpm_min, _system_uA)
+
 /* PM8x41 regulator constraints */
 
 /*	    ID      name     a_on  min_uV   max_uV  supply    hpm_min sys_uA  */
@@ -233,6 +253,12 @@
 PM8X41_VS(LVS2,    "8941_lvs2", 0, "8941_s3");
 PM8X41_VS(LVS3,    "8941_lvs3", 0, "8941_s3");
 
+/*	 ID      name     a_on  min_uV   max_uV  supply  hpm_min sys_uA  */
+KRAIT_PWR(K0, "krait0", 0, 850000,  1100000, NULL,     100000, 0);
+KRAIT_PWR(K1, "krait1", 0, 850000,  1100000, NULL,     100000, 0);
+KRAIT_PWR(K2, "krait2", 0, 850000,  1100000, NULL,     100000, 0);
+KRAIT_PWR(K3, "krait3", 0, 850000,  1100000, NULL,     100000, 0);
+
 #define VREG_DEVICE(_name, _devid)					       \
 		vreg_device_##_name __devinitdata =			       \
 		{							       \
@@ -279,6 +305,10 @@
 static struct platform_device VREG_DEVICE(LVS1, 36);
 static struct platform_device VREG_DEVICE(LVS2, 37);
 static struct platform_device VREG_DEVICE(LVS3, 38);
+static struct platform_device VREG_DEVICE(K0, 39);
+static struct platform_device VREG_DEVICE(K1, 40);
+static struct platform_device VREG_DEVICE(K2, 41);
+static struct platform_device VREG_DEVICE(K3, 42);
 
 struct platform_device *msm_copper_stub_regulator_devices[] __devinitdata = {
 	&vreg_device_S1B,
@@ -319,6 +349,10 @@
 	&vreg_device_LVS1,
 	&vreg_device_LVS2,
 	&vreg_device_LVS3,
+	&vreg_device_K0,
+	&vreg_device_K1,
+	&vreg_device_K2,
+	&vreg_device_K3,
 };
 
 int msm_copper_stub_regulator_devices_len __devinitdata =
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index b5ab440..e08c807 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -400,6 +400,7 @@
 	CLK_DUMMY("iface_clk",	SPI_P_CLK,	"spi_qsd.1",	OFF),
 	CLK_DUMMY("core_clk",	NULL,	"f9966000.i2c", 0),
 	CLK_DUMMY("iface_clk",	NULL,	"f9966000.i2c", 0),
+	CLK_DUMMY("core_clk",	NULL,	"fe12f000.slim",	OFF),
 };
 
 struct clock_init_data msm_dummy_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 3fb6042..5d04786 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -26,25 +26,7 @@
 
 static void __init msm_dt_timer_init(void)
 {
-	struct device_node *node;
-	struct arch_timer tmr;
-	int rc;
-
-	node = of_find_compatible_node(NULL, NULL, "qcom,msm-qtimer");
-	if (!node) {
-		pr_err("no matching timer node found\n");
-		return;
-	}
-
-	tmr.res[0].start = 0;
-	tmr.res[1].start = 0;
-	rc = of_irq_to_resource(node, 0, tmr.res);
-	if (rc < 0)
-		pr_err("interrupt not specified in timer node\n");
-	else
-		arch_timer_register(&tmr);
-
-	of_node_put(node);
+	arch_timer_of_register();
 }
 
 static struct sys_timer msm_dt_timer = {
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index 87fea3f..ce6bf35 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -835,6 +835,7 @@
 	&qcedev_device,
 	&ota_qcrypto_device,
 	&fsm_xo_device,
+	&fsm9xxx_device_watchdog,
 };
 
 static void __init fsm9xxx_init_irq(void)
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index a8ab81a..fcbf2a6 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -102,6 +102,8 @@
 		gpio_bt_sys_rest_en = 114;
 	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		gpio_bt_sys_rest_en = 16;
+	if (machine_is_msm8625_qrd7())
+		gpio_bt_sys_rest_en = 88;
 }
 
 static int bt_set_gpio(int on)
@@ -113,7 +115,7 @@
 			__func__, gpio_bt_sys_rest_en, on);
 	if (on) {
 
-		if (machine_is_msm7627a_evb()) {
+		if (machine_is_msm7627a_evb() || machine_is_msm8625_qrd7()) {
 			rc = gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
 					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
 					GPIO_CFG_2MA),
@@ -128,7 +130,8 @@
 
 		if (!marimba_get_fm_status(&config) &&
 				!marimba_get_bt_status(&config)) {
-			if (machine_is_msm7627a_evb()) {
+			if (machine_is_msm7627a_evb() ||
+					 machine_is_msm8625_qrd7()) {
 				gpio_set_value(gpio_bt_sys_rest_en, 0);
 				rc = gpio_tlmm_config(GPIO_CFG(
 					gpio_bt_sys_rest_en, 0,
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 608eb1e..2269073 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -149,6 +149,7 @@
 	.sensor_platform_info   = &sensor_board_info_s5k4e1,
 	.csi_if                 = 1,
 	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 #ifdef CONFIG_DW9712_ACT
 	.actuator_info = &s5k4e1_actuator_info
 #endif
@@ -178,6 +179,7 @@
 	.sensor_platform_info   = &sensor_board_info_ov7692,
 	.csi_if		 = 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = YUV_SENSOR,
 };
 #endif
 
@@ -225,6 +227,7 @@
 	.sensor_platform_info   = &sensor_board_info_ov5647,
 	.csi_if                 = 1,
 	.camera_type	= BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 
 #ifdef CONFIG_AD5046_ACT
 	.actuator_info = &ad5046_actuator_info
@@ -254,6 +257,7 @@
 	.sensor_platform_info   = &sensor_board_info_mt9e013,
 	.csi_if                 = 1,
 	.camera_type = BACK_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 };
 #endif
 
@@ -279,6 +283,7 @@
 	.sensor_platform_info   = &sensor_board_info_ov9726,
 	.csi_if                 = 1,
 	.camera_type = FRONT_CAMERA_2D,
+	.sensor_type = BAYER_SENSOR,
 };
 #endif
 
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
new file mode 100644
index 0000000..9186203
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -0,0 +1,713 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio_event.h>
+#include <linux/leds.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/i2c.h>
+#include <linux/input/rmi_platformdata.h>
+#include <linux/input/rmi_i2c.h>
+#include <linux/delay.h>
+#include <linux/atmel_maxtouch.h>
+#include <linux/input/ft5x06_ts.h>
+#include <asm/gpio.h>
+#include <asm/mach-types.h>
+#include <mach/rpc_server_handset.h>
+
+#include "devices.h"
+#include "board-msm7627a.h"
+#include "devices-msm7x2xa.h"
+
+#define ATMEL_TS_I2C_NAME "maXTouch"
+#define ATMEL_X_OFFSET 13
+#define ATMEL_Y_OFFSET 0
+
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C) || \
+defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C_MODULE)
+
+#ifndef CLEARPAD3000_ATTEN_GPIO
+#define CLEARPAD3000_ATTEN_GPIO (48)
+#endif
+
+#ifndef CLEARPAD3000_RESET_GPIO
+#define CLEARPAD3000_RESET_GPIO (26)
+#endif
+
+#define KP_INDEX(row, col) ((row)*ARRAY_SIZE(kp_col_gpios) + (col))
+
+static unsigned int kp_row_gpios[] = {31, 32, 33, 34, 35};
+static unsigned int kp_col_gpios[] = {36, 37, 38, 39, 40};
+
+static const unsigned short keymap[ARRAY_SIZE(kp_col_gpios) *
+					  ARRAY_SIZE(kp_row_gpios)] = {
+	[KP_INDEX(0, 0)] = KEY_7,
+	[KP_INDEX(0, 1)] = KEY_DOWN,
+	[KP_INDEX(0, 2)] = KEY_UP,
+	[KP_INDEX(0, 3)] = KEY_RIGHT,
+	[KP_INDEX(0, 4)] = KEY_ENTER,
+
+	[KP_INDEX(1, 0)] = KEY_LEFT,
+	[KP_INDEX(1, 1)] = KEY_SEND,
+	[KP_INDEX(1, 2)] = KEY_1,
+	[KP_INDEX(1, 3)] = KEY_4,
+	[KP_INDEX(1, 4)] = KEY_CLEAR,
+
+	[KP_INDEX(2, 0)] = KEY_6,
+	[KP_INDEX(2, 1)] = KEY_5,
+	[KP_INDEX(2, 2)] = KEY_8,
+	[KP_INDEX(2, 3)] = KEY_3,
+	[KP_INDEX(2, 4)] = KEY_NUMERIC_STAR,
+
+	[KP_INDEX(3, 0)] = KEY_9,
+	[KP_INDEX(3, 1)] = KEY_NUMERIC_POUND,
+	[KP_INDEX(3, 2)] = KEY_0,
+	[KP_INDEX(3, 3)] = KEY_2,
+	[KP_INDEX(3, 4)] = KEY_SLEEP,
+
+	[KP_INDEX(4, 0)] = KEY_BACK,
+	[KP_INDEX(4, 1)] = KEY_HOME,
+	[KP_INDEX(4, 2)] = KEY_MENU,
+	[KP_INDEX(4, 3)] = KEY_VOLUMEUP,
+	[KP_INDEX(4, 4)] = KEY_VOLUMEDOWN,
+};
+
+/* SURF keypad platform device information */
+static struct gpio_event_matrix_info kp_matrix_info = {
+	.info.func	= gpio_event_matrix_func,
+	.keymap		= keymap,
+	.output_gpios	= kp_row_gpios,
+	.input_gpios	= kp_col_gpios,
+	.noutputs	= ARRAY_SIZE(kp_row_gpios),
+	.ninputs	= ARRAY_SIZE(kp_col_gpios),
+	.settle_time.tv_nsec = 40 * NSEC_PER_USEC,
+	.poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
+	.flags		= GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
+			  GPIOKPF_PRINT_UNMAPPED_KEYS,
+};
+
+static struct gpio_event_info *kp_info[] = {
+	&kp_matrix_info.info
+};
+
+static struct gpio_event_platform_data kp_pdata = {
+	.name		= "7x27a_kp",
+	.info		= kp_info,
+	.info_count	= ARRAY_SIZE(kp_info)
+};
+
+static struct platform_device kp_pdev = {
+	.name	= GPIO_EVENT_DEV_NAME,
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &kp_pdata,
+	},
+};
+
+/* 8625 keypad device information */
+static unsigned int kp_row_gpios_8625[] = {31};
+static unsigned int kp_col_gpios_8625[] = {36, 37};
+
+static const unsigned short keymap_8625[] = {
+	KEY_VOLUMEUP,
+	KEY_VOLUMEDOWN,
+};
+
+static struct gpio_event_matrix_info kp_matrix_info_8625 = {
+	.info.func      = gpio_event_matrix_func,
+	.keymap         = keymap_8625,
+	.output_gpios   = kp_row_gpios_8625,
+	.input_gpios    = kp_col_gpios_8625,
+	.noutputs       = ARRAY_SIZE(kp_row_gpios_8625),
+	.ninputs        = ARRAY_SIZE(kp_col_gpios_8625),
+	.settle_time.tv_nsec = 40 * NSEC_PER_USEC,
+	.poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
+	.flags          = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
+			  GPIOKPF_PRINT_UNMAPPED_KEYS,
+};
+
+static struct gpio_event_info *kp_info_8625[] = {
+	&kp_matrix_info_8625.info,
+};
+
+static struct gpio_event_platform_data kp_pdata_8625 = {
+	.name           = "8625_kp",
+	.info           = kp_info_8625,
+	.info_count     = ARRAY_SIZE(kp_info_8625)
+};
+
+static struct platform_device kp_pdev_8625 = {
+	.name   = GPIO_EVENT_DEV_NAME,
+	.id     = -1,
+	.dev    = {
+		.platform_data  = &kp_pdata_8625,
+	},
+};
+
+#define LED_GPIO_PDM 96
+#define LED_RED_GPIO_8625 49
+#define LED_GREEN_GPIO_8625 34
+
+static struct gpio_led gpio_leds_config_8625[] = {
+	{
+		.name = "green",
+		.gpio = LED_GREEN_GPIO_8625,
+	},
+	{
+		.name = "red",
+		.gpio = LED_RED_GPIO_8625,
+	},
+};
+
+static struct gpio_led_platform_data gpio_leds_pdata_8625 = {
+	.num_leds = ARRAY_SIZE(gpio_leds_config_8625),
+	.leds = gpio_leds_config_8625,
+};
+
+static struct platform_device gpio_leds_8625 = {
+	.name          = "leds-gpio",
+	.id            = -1,
+	.dev           = {
+		.platform_data = &gpio_leds_pdata_8625,
+	},
+};
+
+#define MXT_TS_IRQ_GPIO         48
+#define MXT_TS_RESET_GPIO       26
+
+static const u8 mxt_config_data[] = {
+	/* T6 Object */
+	0, 0, 0, 0, 0, 0,
+	/* T38 Object */
+	16, 0, 0, 0, 0, 0, 0, 0,
+	/* T7 Object */
+	32, 16, 50,
+	/* T8 Object */
+	30, 0, 20, 20, 0, 0, 20, 0, 50, 0,
+	/* T9 Object */
+	3, 0, 0, 18, 11, 0, 32, 75, 3, 3,
+	0, 1, 1, 0, 10, 10, 10, 10, 31, 3,
+	223, 1, 11, 11, 15, 15, 151, 43, 145, 80,
+	100, 15, 0, 0, 0,
+	/* T15 Object */
+	131, 0, 11, 11, 1, 1, 0, 45, 3, 0,
+	0,
+	/* T18 Object */
+	0, 0,
+	/* T19 Object */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0,
+	/* T23 Object */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0,
+	/* T25 Object */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0,
+	/* T40 Object */
+	0, 0, 0, 0, 0,
+	/* T42 Object */
+	0, 0, 0, 0, 0, 0, 0, 0,
+	/* T46 Object */
+	0, 2, 32, 48, 0, 0, 0, 0, 0,
+	/* T47 Object */
+	1, 20, 60, 5, 2, 50, 40, 0, 0, 40,
+	/* T48 Object */
+	1, 12, 80, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+	10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+	0, 0, 0, 0, 16, 65, 3, 1, 1, 0,
+	10, 10, 10, 0, 0, 15, 15, 154, 58, 145,
+	80, 100, 15, 3,
+};
+
+static struct mxt_config_info mxt_config_array[] = {
+	{
+		.config		= mxt_config_data,
+		.config_length	= ARRAY_SIZE(mxt_config_data),
+		.family_id	= 0x81,
+		.variant_id	= 0x01,
+		.version	= 0x10,
+		.build		= 0xAA,
+	},
+};
+
+static int mxt_key_codes[MXT_KEYARRAY_MAX_KEYS] = {
+	[0] = KEY_HOME,
+	[1] = KEY_MENU,
+	[9] = KEY_BACK,
+	[10] = KEY_SEARCH,
+};
+
+static struct mxt_platform_data mxt_platform_data = {
+	.config_array		= mxt_config_array,
+	.config_array_size	= ARRAY_SIZE(mxt_config_array),
+	.panel_minx		= 0,
+	.panel_maxx		= 479,
+	.panel_miny		= 0,
+	.panel_maxy		= 799,
+	.disp_minx		= 0,
+	.disp_maxx		= 479,
+	.disp_miny		= 0,
+	.disp_maxy		= 799,
+	.irqflags		= IRQF_TRIGGER_FALLING,
+	.i2c_pull_up		= true,
+	.reset_gpio		= MXT_TS_RESET_GPIO,
+	.irq_gpio		= MXT_TS_IRQ_GPIO,
+	.key_codes		= mxt_key_codes,
+};
+
+static struct i2c_board_info mxt_device_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
+		.platform_data = &mxt_platform_data,
+		.irq = MSM_GPIO_TO_INT(MXT_TS_IRQ_GPIO),
+	},
+};
+
+static int synaptics_touchpad_setup(void);
+
+static struct msm_gpio clearpad3000_cfg_data[] = {
+	{GPIO_CFG(CLEARPAD3000_ATTEN_GPIO, 0, GPIO_CFG_INPUT,
+			GPIO_CFG_NO_PULL, GPIO_CFG_6MA), "rmi4_attn"},
+	{GPIO_CFG(CLEARPAD3000_RESET_GPIO, 0, GPIO_CFG_OUTPUT,
+			GPIO_CFG_PULL_DOWN, GPIO_CFG_8MA), "rmi4_reset"},
+};
+
+static struct rmi_XY_pair rmi_offset = {.x = 0, .y = 0};
+static struct rmi_range rmi_clipx = {.min = 48, .max = 980};
+static struct rmi_range rmi_clipy = {.min = 7, .max = 1647};
+static struct rmi_f11_functiondata synaptics_f11_data = {
+	.swap_axes = false,
+	.flipX = false,
+	.flipY = false,
+	.offset = &rmi_offset,
+	.button_height = 113,
+	.clipX = &rmi_clipx,
+	.clipY = &rmi_clipy,
+};
+
+#define MAX_LEN		100
+
+static ssize_t clearpad3000_virtual_keys_register(struct kobject *kobj,
+		     struct kobj_attribute *attr, char *buf)
+{
+	char *virtual_keys = __stringify(EV_KEY) ":" __stringify(KEY_MENU) \
+			     ":60:830:120:60" ":" __stringify(EV_KEY) \
+			     ":" __stringify(KEY_HOME)   ":180:830:120:60" \
+				":" __stringify(EV_KEY) ":" \
+				__stringify(KEY_SEARCH) ":300:830:120:60" \
+				":" __stringify(EV_KEY) ":" \
+			__stringify(KEY_BACK)   ":420:830:120:60" "\n";
+
+	return snprintf(buf, strnlen(virtual_keys, MAX_LEN) + 1 , "%s",
+			virtual_keys);
+}
+
+static struct kobj_attribute clearpad3000_virtual_keys_attr = {
+	.attr = {
+		.name = "virtualkeys.sensor00fn11",
+		.mode = S_IRUGO,
+	},
+	.show = &clearpad3000_virtual_keys_register,
+};
+
+static struct attribute *virtual_key_properties_attrs[] = {
+	&clearpad3000_virtual_keys_attr.attr,
+	NULL
+};
+
+static struct attribute_group virtual_key_properties_attr_group = {
+	.attrs = virtual_key_properties_attrs,
+};
+
+struct kobject *virtual_key_properties_kobj;
+
+static struct rmi_functiondata synaptics_functiondata[] = {
+	{
+		.function_index = RMI_F11_INDEX,
+		.data = &synaptics_f11_data,
+	},
+};
+
+static struct rmi_functiondata_list synaptics_perfunctiondata = {
+	.count = ARRAY_SIZE(synaptics_functiondata),
+	.functiondata = synaptics_functiondata,
+};
+
+static struct rmi_sensordata synaptics_sensordata = {
+	.perfunctiondata = &synaptics_perfunctiondata,
+	.rmi_sensor_setup	= synaptics_touchpad_setup,
+};
+
+static struct rmi_i2c_platformdata synaptics_platformdata = {
+	.i2c_address = 0x2c,
+	.irq_type = IORESOURCE_IRQ_LOWLEVEL,
+	.sensordata = &synaptics_sensordata,
+};
+
+static struct i2c_board_info synaptic_i2c_clearpad3k[] = {
+	{
+	I2C_BOARD_INFO("rmi4_ts", 0x2c),
+	.platform_data = &synaptics_platformdata,
+	},
+};
+
+static int synaptics_touchpad_setup(void)
+{
+	int retval = 0;
+
+	virtual_key_properties_kobj =
+		kobject_create_and_add("board_properties", NULL);
+	if (virtual_key_properties_kobj)
+		retval = sysfs_create_group(virtual_key_properties_kobj,
+				&virtual_key_properties_attr_group);
+	if (!virtual_key_properties_kobj || retval)
+		pr_err("failed to create ft5202 board_properties\n");
+
+	retval = msm_gpios_request_enable(clearpad3000_cfg_data,
+		    sizeof(clearpad3000_cfg_data)/sizeof(struct msm_gpio));
+	if (retval) {
+		pr_err("%s:Failed to obtain touchpad GPIO %d. Code: %d.",
+				__func__, CLEARPAD3000_ATTEN_GPIO, retval);
+		retval = 0; /* ignore the err */
+	}
+	synaptics_platformdata.irq = gpio_to_irq(CLEARPAD3000_ATTEN_GPIO);
+
+	gpio_set_value(CLEARPAD3000_RESET_GPIO, 0);
+	usleep(10000);
+	gpio_set_value(CLEARPAD3000_RESET_GPIO, 1);
+	usleep(50000);
+
+	return retval;
+}
+#endif
+
+static struct regulator_bulk_data regs_atmel[] = {
+	{ .supply = "ldo2",  .min_uV = 2850000, .max_uV = 2850000 },
+	{ .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
+};
+
+#define ATMEL_TS_GPIO_IRQ 82
+
+static int atmel_ts_power_on(bool on)
+{
+	int rc = on ?
+		regulator_bulk_enable(ARRAY_SIZE(regs_atmel), regs_atmel) :
+		regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
+
+	if (rc)
+		pr_err("%s: could not %sable regulators: %d\n",
+				__func__, on ? "en" : "dis", rc);
+	else
+		msleep(50);
+
+	return rc;
+}
+
+static int atmel_ts_platform_init(struct i2c_client *client)
+{
+	int rc;
+	struct device *dev = &client->dev;
+
+	rc = regulator_bulk_get(dev, ARRAY_SIZE(regs_atmel), regs_atmel);
+	if (rc) {
+		dev_err(dev, "%s: could not get regulators: %d\n",
+				__func__, rc);
+		goto out;
+	}
+
+	rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_atmel), regs_atmel);
+	if (rc) {
+		dev_err(dev, "%s: could not set voltages: %d\n",
+				__func__, rc);
+		goto reg_free;
+	}
+
+	rc = gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
+				GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
+				GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+	if (rc) {
+		dev_err(dev, "%s: gpio_tlmm_config for %d failed\n",
+			__func__, ATMEL_TS_GPIO_IRQ);
+		goto reg_free;
+	}
+
+	/* configure touchscreen interrupt gpio */
+	rc = gpio_request(ATMEL_TS_GPIO_IRQ, "atmel_maxtouch_gpio");
+	if (rc) {
+		dev_err(dev, "%s: unable to request gpio %d\n",
+			__func__, ATMEL_TS_GPIO_IRQ);
+		goto ts_gpio_tlmm_unconfig;
+	}
+
+	rc = gpio_direction_input(ATMEL_TS_GPIO_IRQ);
+	if (rc < 0) {
+		dev_err(dev, "%s: unable to set the direction of gpio %d\n",
+			__func__, ATMEL_TS_GPIO_IRQ);
+		goto free_ts_gpio;
+	}
+	return 0;
+
+free_ts_gpio:
+	gpio_free(ATMEL_TS_GPIO_IRQ);
+ts_gpio_tlmm_unconfig:
+	gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
+				GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
+				GPIO_CFG_2MA), GPIO_CFG_DISABLE);
+reg_free:
+	regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
+out:
+	return rc;
+}
+
+static int atmel_ts_platform_exit(struct i2c_client *client)
+{
+	gpio_free(ATMEL_TS_GPIO_IRQ);
+	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_free(ARRAY_SIZE(regs_atmel), regs_atmel);
+	return 0;
+}
+
+static u8 atmel_ts_read_chg(void)
+{
+	return gpio_get_value(ATMEL_TS_GPIO_IRQ);
+}
+
+static u8 atmel_ts_valid_interrupt(void)
+{
+	return !atmel_ts_read_chg();
+}
+
+
+static struct maxtouch_platform_data atmel_ts_pdata = {
+	.numtouch = 4,
+	.init_platform_hw = atmel_ts_platform_init,
+	.exit_platform_hw = atmel_ts_platform_exit,
+	.power_on = atmel_ts_power_on,
+	.display_res_x = 480,
+	.display_res_y = 864,
+	.min_x = ATMEL_X_OFFSET,
+	.max_x = (505 - ATMEL_X_OFFSET),
+	.min_y = ATMEL_Y_OFFSET,
+	.max_y = (863 - ATMEL_Y_OFFSET),
+	.valid_interrupt = atmel_ts_valid_interrupt,
+	.read_chg = atmel_ts_read_chg,
+};
+
+static struct i2c_board_info atmel_ts_i2c_info[] __initdata = {
+	{
+		I2C_BOARD_INFO(ATMEL_TS_I2C_NAME, 0x4a),
+		.platform_data = &atmel_ts_pdata,
+		.irq = MSM_GPIO_TO_INT(ATMEL_TS_GPIO_IRQ),
+	},
+};
+
+static struct msm_handset_platform_data hs_platform_data = {
+	.hs_name = "7k_handset",
+	.pwr_key_delay_ms = 500, /* 0 will disable end key */
+};
+
+static struct platform_device hs_pdev = {
+	.name   = "msm-handset",
+	.id     = -1,
+	.dev    = {
+		.platform_data = &hs_platform_data,
+	},
+};
+
+#define FT5X06_IRQ_GPIO		48
+#define FT5X06_RESET_GPIO	26
+
+static ssize_t
+ft5x06_virtual_keys_register(struct kobject *kobj,
+			     struct kobj_attribute *attr,
+			     char *buf)
+{
+	return snprintf(buf, 200,
+	__stringify(EV_KEY) ":" __stringify(KEY_MENU)  ":40:510:80:60"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME)   ":120:510:80:60"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":200:510:80:60"
+	":" __stringify(EV_KEY) ":" __stringify(KEY_BACK)   ":280:510:80:60"
+	"\n");
+}
+
+static struct kobj_attribute ft5x06_virtual_keys_attr = {
+	.attr = {
+		.name = "virtualkeys.ft5x06_ts",
+		.mode = S_IRUGO,
+	},
+	.show = &ft5x06_virtual_keys_register,
+};
+
+static struct attribute *ft5x06_virtual_key_properties_attrs[] = {
+	&ft5x06_virtual_keys_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ft5x06_virtual_key_properties_attr_group = {
+	.attrs = ft5x06_virtual_key_properties_attrs,
+};
+
+struct kobject *ft5x06_virtual_key_properties_kobj;
+
+static struct ft5x06_ts_platform_data ft5x06_platformdata = {
+	.x_max		= 320,
+	.y_max		= 480,
+	.reset_gpio	= FT5X06_RESET_GPIO,
+	.irq_gpio	= FT5X06_IRQ_GPIO,
+	.irqflags	= IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+};
+
+static struct i2c_board_info ft5x06_device_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("ft5x06_ts", 0x38),
+		.platform_data = &ft5x06_platformdata,
+		.irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO),
+	},
+};
+
+static void ft5x06_touchpad_setup(void)
+{
+	int rc;
+
+	rc = gpio_tlmm_config(GPIO_CFG(FT5X06_IRQ_GPIO, 0,
+			GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
+			GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+	if (rc)
+		pr_err("%s: gpio_tlmm_config for %d failed\n",
+			__func__, FT5X06_IRQ_GPIO);
+
+	rc = gpio_tlmm_config(GPIO_CFG(FT5X06_RESET_GPIO, 0,
+			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+			GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+	if (rc)
+		pr_err("%s: gpio_tlmm_config for %d failed\n",
+			__func__, FT5X06_RESET_GPIO);
+
+	ft5x06_virtual_key_properties_kobj =
+			kobject_create_and_add("board_properties", NULL);
+
+	if (ft5x06_virtual_key_properties_kobj)
+		rc = sysfs_create_group(ft5x06_virtual_key_properties_kobj,
+				&ft5x06_virtual_key_properties_attr_group);
+
+	if (!ft5x06_virtual_key_properties_kobj || rc)
+		pr_err("%s: failed to create board_properties\n", __func__);
+
+	i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+				ft5x06_device_info,
+				ARRAY_SIZE(ft5x06_device_info));
+}
+
+void __init msm7627a_add_io_devices(void)
+{
+	/* touchscreen */
+	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
+		atmel_ts_pdata.min_x = 0;
+		atmel_ts_pdata.max_x = 480;
+		atmel_ts_pdata.min_y = 0;
+		atmel_ts_pdata.max_y = 320;
+	}
+
+	i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+				atmel_ts_i2c_info,
+				ARRAY_SIZE(atmel_ts_i2c_info));
+	/* keypad */
+	platform_device_register(&kp_pdev);
+
+	/* headset */
+	platform_device_register(&hs_pdev);
+
+	/* LED: configure it as a pdm function */
+	if (gpio_tlmm_config(GPIO_CFG(LED_GPIO_PDM, 3,
+				GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+				GPIO_CFG_8MA), GPIO_CFG_ENABLE))
+		pr_err("%s: gpio_tlmm_config for %d failed\n",
+			__func__, LED_GPIO_PDM);
+	else
+		platform_device_register(&led_pdev);
+
+	/* Vibrator */
+	if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
+		msm_init_pmic_vibrator();
+}
+
+void __init qrd7627a_add_io_devices(void)
+{
+	int rc;
+
+	/* touchscreen */
+	if (machine_is_msm7627a_qrd1()) {
+		i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+					synaptic_i2c_clearpad3k,
+					ARRAY_SIZE(synaptic_i2c_clearpad3k));
+	} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
+		rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_IRQ_GPIO, 0,
+				GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
+				GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s: gpio_tlmm_config for %d failed\n",
+				__func__, MXT_TS_IRQ_GPIO);
+		}
+
+		rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_RESET_GPIO, 0,
+				GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+				GPIO_CFG_8MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s: gpio_tlmm_config for %d failed\n",
+				__func__, MXT_TS_RESET_GPIO);
+		}
+
+		i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+					mxt_device_info,
+					ARRAY_SIZE(mxt_device_info));
+	} else if (machine_is_msm7627a_qrd3()) {
+		ft5x06_touchpad_setup();
+	}
+
+	/* headset */
+	platform_device_register(&hs_pdev);
+
+	/* vibrator */
+#ifdef CONFIG_MSM_RPC_VIBRATOR
+	msm_init_pmic_vibrator();
+#endif
+
+	/* keypad */
+	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
+		platform_device_register(&kp_pdev_8625);
+
+	/* leds */
+	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
+		rc = gpio_tlmm_config(GPIO_CFG(LED_RED_GPIO_8625, 0,
+				GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
+				GPIO_CFG_16MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s: gpio_tlmm_config for %d failed\n",
+				__func__, LED_RED_GPIO_8625);
+		}
+
+		rc = gpio_tlmm_config(GPIO_CFG(LED_GREEN_GPIO_8625, 0,
+				GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
+				GPIO_CFG_16MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s: gpio_tlmm_config for %d failed\n",
+				__func__, LED_GREEN_GPIO_8625);
+		}
+
+		platform_device_register(&gpio_leds_8625);
+	}
+}
diff --git a/arch/arm/mach-msm/board-msm7627a.h b/arch/arm/mach-msm/board-msm7627a.h
index bde9b61..68e333f 100644
--- a/arch/arm/mach-msm/board-msm7627a.h
+++ b/arch/arm/mach-msm/board-msm7627a.h
@@ -104,4 +104,7 @@
 
 void __init msm7627a_camera_init(void);
 u32 msm7627a_power_collapse_latency(enum msm_pm_sleep_mode);
+
+void __init msm7627a_add_io_devices(void);
+void __init qrd7627a_add_io_devices(void);
 #endif
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index e75a963..1da4794 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -950,7 +950,7 @@
 {
 	msm7x27a_reserve();
 	memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
-	msm_pm_8625_boot_pdata.p_addr = memblock_alloc(SZ_16, SZ_64K);
+	memblock_remove(MSM8625_WARM_BOOT_PHYS, SZ_32);
 }
 
 static void __init msm7x27a_device_i2c_init(void)
@@ -1001,215 +1001,6 @@
 	iounmap(ebi2_cfg_ptr);
 }
 
-#define ATMEL_TS_I2C_NAME "maXTouch"
-
-static struct regulator_bulk_data regs_atmel[] = {
-	{ .supply = "ldo2",  .min_uV = 2850000, .max_uV = 2850000 },
-	{ .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
-};
-
-#define ATMEL_TS_GPIO_IRQ 82
-
-static int atmel_ts_power_on(bool on)
-{
-	int rc = on ?
-		regulator_bulk_enable(ARRAY_SIZE(regs_atmel), regs_atmel) :
-		regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
-
-	if (rc)
-		pr_err("%s: could not %sable regulators: %d\n",
-				__func__, on ? "en" : "dis", rc);
-	else
-		msleep(50);
-
-	return rc;
-}
-
-static int atmel_ts_platform_init(struct i2c_client *client)
-{
-	int rc;
-	struct device *dev = &client->dev;
-
-	rc = regulator_bulk_get(dev, ARRAY_SIZE(regs_atmel), regs_atmel);
-	if (rc) {
-		dev_err(dev, "%s: could not get regulators: %d\n",
-				__func__, rc);
-		goto out;
-	}
-
-	rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_atmel), regs_atmel);
-	if (rc) {
-		dev_err(dev, "%s: could not set voltages: %d\n",
-				__func__, rc);
-		goto reg_free;
-	}
-
-	rc = gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
-				GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
-				GPIO_CFG_8MA), GPIO_CFG_ENABLE);
-	if (rc) {
-		dev_err(dev, "%s: gpio_tlmm_config for %d failed\n",
-			__func__, ATMEL_TS_GPIO_IRQ);
-		goto reg_free;
-	}
-
-	/* configure touchscreen interrupt gpio */
-	rc = gpio_request(ATMEL_TS_GPIO_IRQ, "atmel_maxtouch_gpio");
-	if (rc) {
-		dev_err(dev, "%s: unable to request gpio %d\n",
-			__func__, ATMEL_TS_GPIO_IRQ);
-		goto ts_gpio_tlmm_unconfig;
-	}
-
-	rc = gpio_direction_input(ATMEL_TS_GPIO_IRQ);
-	if (rc < 0) {
-		dev_err(dev, "%s: unable to set the direction of gpio %d\n",
-			__func__, ATMEL_TS_GPIO_IRQ);
-		goto free_ts_gpio;
-	}
-	return 0;
-
-free_ts_gpio:
-	gpio_free(ATMEL_TS_GPIO_IRQ);
-ts_gpio_tlmm_unconfig:
-	gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
-				GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
-				GPIO_CFG_2MA), GPIO_CFG_DISABLE);
-reg_free:
-	regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
-out:
-	return rc;
-}
-
-static int atmel_ts_platform_exit(struct i2c_client *client)
-{
-	gpio_free(ATMEL_TS_GPIO_IRQ);
-	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_free(ARRAY_SIZE(regs_atmel), regs_atmel);
-	return 0;
-}
-
-static u8 atmel_ts_read_chg(void)
-{
-	return gpio_get_value(ATMEL_TS_GPIO_IRQ);
-}
-
-static u8 atmel_ts_valid_interrupt(void)
-{
-	return !atmel_ts_read_chg();
-}
-
-#define ATMEL_X_OFFSET 13
-#define ATMEL_Y_OFFSET 0
-
-static struct maxtouch_platform_data atmel_ts_pdata = {
-	.numtouch = 4,
-	.init_platform_hw = atmel_ts_platform_init,
-	.exit_platform_hw = atmel_ts_platform_exit,
-	.power_on = atmel_ts_power_on,
-	.display_res_x = 480,
-	.display_res_y = 864,
-	.min_x = ATMEL_X_OFFSET,
-	.max_x = (505 - ATMEL_X_OFFSET),
-	.min_y = ATMEL_Y_OFFSET,
-	.max_y = (863 - ATMEL_Y_OFFSET),
-	.valid_interrupt = atmel_ts_valid_interrupt,
-	.read_chg = atmel_ts_read_chg,
-};
-
-static struct i2c_board_info atmel_ts_i2c_info[] __initdata = {
-	{
-		I2C_BOARD_INFO(ATMEL_TS_I2C_NAME, 0x4a),
-		.platform_data = &atmel_ts_pdata,
-		.irq = MSM_GPIO_TO_INT(ATMEL_TS_GPIO_IRQ),
-	},
-};
-
-#define KP_INDEX(row, col) ((row)*ARRAY_SIZE(kp_col_gpios) + (col))
-
-static unsigned int kp_row_gpios[] = {31, 32, 33, 34, 35};
-static unsigned int kp_col_gpios[] = {36, 37, 38, 39, 40};
-
-static const unsigned short keymap[ARRAY_SIZE(kp_col_gpios) *
-					  ARRAY_SIZE(kp_row_gpios)] = {
-	[KP_INDEX(0, 0)] = KEY_7,
-	[KP_INDEX(0, 1)] = KEY_DOWN,
-	[KP_INDEX(0, 2)] = KEY_UP,
-	[KP_INDEX(0, 3)] = KEY_RIGHT,
-	[KP_INDEX(0, 4)] = KEY_ENTER,
-
-	[KP_INDEX(1, 0)] = KEY_LEFT,
-	[KP_INDEX(1, 1)] = KEY_SEND,
-	[KP_INDEX(1, 2)] = KEY_1,
-	[KP_INDEX(1, 3)] = KEY_4,
-	[KP_INDEX(1, 4)] = KEY_CLEAR,
-
-	[KP_INDEX(2, 0)] = KEY_6,
-	[KP_INDEX(2, 1)] = KEY_5,
-	[KP_INDEX(2, 2)] = KEY_8,
-	[KP_INDEX(2, 3)] = KEY_3,
-	[KP_INDEX(2, 4)] = KEY_NUMERIC_STAR,
-
-	[KP_INDEX(3, 0)] = KEY_9,
-	[KP_INDEX(3, 1)] = KEY_NUMERIC_POUND,
-	[KP_INDEX(3, 2)] = KEY_0,
-	[KP_INDEX(3, 3)] = KEY_2,
-	[KP_INDEX(3, 4)] = KEY_SLEEP,
-
-	[KP_INDEX(4, 0)] = KEY_BACK,
-	[KP_INDEX(4, 1)] = KEY_HOME,
-	[KP_INDEX(4, 2)] = KEY_MENU,
-	[KP_INDEX(4, 3)] = KEY_VOLUMEUP,
-	[KP_INDEX(4, 4)] = KEY_VOLUMEDOWN,
-};
-
-/* SURF keypad platform device information */
-static struct gpio_event_matrix_info kp_matrix_info = {
-	.info.func	= gpio_event_matrix_func,
-	.keymap		= keymap,
-	.output_gpios	= kp_row_gpios,
-	.input_gpios	= kp_col_gpios,
-	.noutputs	= ARRAY_SIZE(kp_row_gpios),
-	.ninputs	= ARRAY_SIZE(kp_col_gpios),
-	.settle_time.tv_nsec = 40 * NSEC_PER_USEC,
-	.poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
-	.flags		= GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
-			  GPIOKPF_PRINT_UNMAPPED_KEYS,
-};
-
-static struct gpio_event_info *kp_info[] = {
-	&kp_matrix_info.info
-};
-
-static struct gpio_event_platform_data kp_pdata = {
-	.name		= "7x27a_kp",
-	.info		= kp_info,
-	.info_count	= ARRAY_SIZE(kp_info)
-};
-
-static struct platform_device kp_pdev = {
-	.name	= GPIO_EVENT_DEV_NAME,
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &kp_pdata,
-	},
-};
-
-static struct msm_handset_platform_data hs_platform_data = {
-	.hs_name = "7k_handset",
-	.pwr_key_delay_ms = 500, /* 0 will disable end key */
-};
-
-static struct platform_device hs_pdev = {
-	.name   = "msm-handset",
-	.id     = -1,
-	.dev    = {
-		.platform_data = &hs_platform_data,
-	},
-};
-
 static struct platform_device msm_proccomm_regulator_dev = {
 	.name   = PROCCOMM_REGULATOR_DEV_NAME,
 	.id     = -1,
@@ -1262,7 +1053,6 @@
 	msm8x25_spm_device_init();
 }
 
-#define LED_GPIO_PDM		96
 #define UART1DM_RX_GPIO		45
 
 #if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
@@ -1330,39 +1120,6 @@
 	}
 }
 
-static void __init msm7x27a_add_io_devices(void)
-{
-	/* touchscreen */
-	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
-		atmel_ts_pdata.min_x = 0;
-		atmel_ts_pdata.max_x = 480;
-		atmel_ts_pdata.min_y = 0;
-		atmel_ts_pdata.max_y = 320;
-	}
-
-	i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
-				atmel_ts_i2c_info,
-				ARRAY_SIZE(atmel_ts_i2c_info));
-	/* keypad */
-	platform_device_register(&kp_pdev);
-
-	/* headset */
-	platform_device_register(&hs_pdev);
-
-	/* LED: configure it as a pdm function */
-	if (gpio_tlmm_config(GPIO_CFG(LED_GPIO_PDM, 3,
-				GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
-				GPIO_CFG_8MA), GPIO_CFG_ENABLE))
-		pr_err("%s: gpio_tlmm_config for %d failed\n",
-			__func__, LED_GPIO_PDM);
-	else
-		platform_device_register(&led_pdev);
-
-	/* Vibrator */
-	if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
-		msm_init_pmic_vibrator();
-}
-
 static void __init msm7x27a_pm_init(void)
 {
 	if (machine_is_msm8625_surf()) {
@@ -1407,7 +1164,7 @@
 	register_i2c_devices();
 	msm7627a_bt_power_init();
 	msm7627a_camera_init();
-	msm7x27a_add_io_devices();
+	msm7627a_add_io_devices();
 	/*7x25a kgsl initializations*/
 	msm7x25a_kgsl_3d0_init();
 }
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index f181133..3387440 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -433,7 +433,7 @@
 			.name = "8901_s0",
 			.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
 			.min_uV = 800000,
-			.max_uV = 1250000,
+			.max_uV = 1325000,
 		},
 		.consumer_supplies = vreg_consumers_8901_S0,
 		.num_consumer_supplies = ARRAY_SIZE(vreg_consumers_8901_S0),
@@ -444,7 +444,7 @@
 			.name = "8901_s1",
 			.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
 			.min_uV = 800000,
-			.max_uV = 1250000,
+			.max_uV = 1325000,
 		},
 		.consumer_supplies = vreg_consumers_8901_S1,
 		.num_consumer_supplies = ARRAY_SIZE(vreg_consumers_8901_S1),
@@ -924,7 +924,7 @@
 		[MSM_RPMRS_VDD_MEM_RET_LOW]     = 500,
 		[MSM_RPMRS_VDD_MEM_RET_HIGH]    = 750,
 		[MSM_RPMRS_VDD_MEM_ACTIVE]      = 1000,
-		[MSM_RPMRS_VDD_MEM_MAX]         = 1250,
+		[MSM_RPMRS_VDD_MEM_MAX]         = 1325,
 	},
 	.vdd_dig_levels = {
 		[MSM_RPMRS_VDD_DIG_RET_LOW]     = 500,
@@ -2629,10 +2629,12 @@
 	if (machine_is_msm8x60_fluid()) {
 		/* fluid has different firmware, gpios */
 		pdata->pil_name = DSPS_PIL_FLUID_NAME;
+		msm_pil_dsps.dev.platform_data = DSPS_PIL_FLUID_NAME;
 		pdata->gpios = dsps_fluid_gpios;
 		pdata->gpios_num = ARRAY_SIZE(dsps_fluid_gpios);
 	} else {
 		pdata->pil_name = DSPS_PIL_GENERIC_NAME;
+		msm_pil_dsps.dev.platform_data = DSPS_PIL_GENERIC_NAME;
 		pdata->gpios = dsps_surf_gpios;
 		pdata->gpios_num = ARRAY_SIZE(dsps_surf_gpios);
 	}
@@ -2703,7 +2705,12 @@
 #define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
 #define MSM_ION_MM_SIZE		0x3600000 /* (54MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
+#ifdef CONFIG_FB_MSM_OVERLAY1_WRITEBACK
+#define MSM_ION_WB_SIZE		0xC00000 /* 12MB */
+#else
 #define MSM_ION_WB_SIZE		0x600000 /* 6MB */
+#endif
+
 #define MSM_ION_QSECOM_SIZE	0x600000 /* (6MB) */
 #define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
 
@@ -2765,6 +2772,8 @@
 	}
 };
 
+static void set_mdp_clocks_for_wuxga(void);
+
 static int msm_fb_detect_panel(const char *name)
 {
 	if (machine_is_msm8x60_fluid()) {
@@ -2819,8 +2828,11 @@
 
 	if (!strncmp(name, HDMI_PANEL_NAME,
 			strnlen(HDMI_PANEL_NAME,
-				PANEL_NAME_MAX_LEN)))
+				PANEL_NAME_MAX_LEN))) {
+		if (hdmi_is_primary)
+			set_mdp_clocks_for_wuxga();
 		return 0;
+	}
 
 	if (!strncmp(name, TVOUT_PANEL_NAME,
 			strnlen(TVOUT_PANEL_NAME,
@@ -3185,6 +3197,7 @@
 			pr_debug("HDMI is the primary display by"
 				" boot parameter\n");
 			hdmi_is_primary = 1;
+			set_mdp_clocks_for_wuxga();
 		}
 	}
 	if (strnlen(ext_panel, PANEL_NAME_MAX_LEN)) {
@@ -4090,7 +4103,7 @@
 /* RPM early regulator constraints */
 static struct rpm_regulator_init_data rpm_regulator_early_init_data[] = {
 	/*	 ID       a_on pd ss min_uV   max_uV   init_ip    freq */
-	RPM_SMPS(PM8058_S0, 0, 1, 1,  500000, 1250000, SMPS_HMIN, 1p60),
+	RPM_SMPS(PM8058_S0, 0, 1, 1,  500000, 1325000, SMPS_HMIN, 1p60),
 	RPM_SMPS(PM8058_S1, 0, 1, 1,  500000, 1250000, SMPS_HMIN, 1p60),
 };
 
@@ -5136,6 +5149,7 @@
 	&msm_pil_q6v3,
 	&msm_pil_modem,
 	&msm_pil_tzapps,
+	&msm_pil_dsps,
 #ifdef CONFIG_I2C_QUP
 	&msm_gsbi3_qup_i2c_device,
 	&msm_gsbi4_qup_i2c_device,
@@ -9224,51 +9238,6 @@
 	},
 };
 
-#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_SMI,
-		.ab = 2000000000,
-		.ib = 2000000000,
-	 },
-	 /* Master and slaves can be from different fabrics */
-	 {
-		.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
 #ifdef CONFIG_FB_MSM_LCDC_DSUB
 static struct msm_bus_vectors mdp_sd_smi_vectors[] = {
 	/* Default case static display/UI/2d/3d if FB SMI */
@@ -9463,7 +9432,6 @@
 		mdp_1080p_vectors,
 	},
 };
-#endif
 static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
 	mdp_bus_scale_usecases,
 	ARRAY_SIZE(mdp_bus_scale_usecases),
@@ -9819,6 +9787,45 @@
 #endif
 }
 
+/**
+ * Set MDP clocks to high frequency to avoid underflow when
+ * using high resolution 1200x1920 WUXGA/HDMI as primary panels
+ */
+static void set_mdp_clocks_for_wuxga(void)
+{
+	int i;
+
+	mdp_sd_smi_vectors[0].ab = 2000000000;
+	mdp_sd_smi_vectors[0].ib = 2000000000;
+	mdp_sd_smi_vectors[1].ab = 2000000000;
+	mdp_sd_smi_vectors[1].ib = 2000000000;
+
+	mdp_sd_ebi_vectors[0].ab = 2000000000;
+	mdp_sd_ebi_vectors[0].ib = 2000000000;
+	mdp_sd_ebi_vectors[1].ab = 2000000000;
+	mdp_sd_ebi_vectors[1].ib = 2000000000;
+
+	mdp_vga_vectors[0].ab = 2000000000;
+	mdp_vga_vectors[0].ib = 2000000000;
+	mdp_vga_vectors[1].ab = 2000000000;
+	mdp_vga_vectors[1].ib = 2000000000;
+
+	mdp_720p_vectors[0].ab = 2000000000;
+	mdp_720p_vectors[0].ib = 2000000000;
+	mdp_720p_vectors[1].ab = 2000000000;
+	mdp_720p_vectors[1].ib = 2000000000;
+
+	mdp_1080p_vectors[0].ab = 2000000000;
+	mdp_1080p_vectors[0].ib = 2000000000;
+	mdp_1080p_vectors[1].ab = 2000000000;
+	mdp_1080p_vectors[1].ib = 2000000000;
+
+	mdp_pdata.mdp_core_clk_rate = 200000000;
+
+	for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
+		mdp_core_clk_rate_table[i] = 200000000;
+}
+
 #if (defined(CONFIG_MARIMBA_CORE)) && \
 	(defined(CONFIG_MSM_BT_POWER) || defined(CONFIG_MSM_BT_POWER_MODULE))
 
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 91bc1ab..7709560 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -130,219 +130,6 @@
 #define MSM_PMEM_ADSP_SIZE      0x1100000
 #endif
 
-#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C) || \
-defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C_MODULE)
-
-#ifndef CLEARPAD3000_ATTEN_GPIO
-#define CLEARPAD3000_ATTEN_GPIO (48)
-#endif
-
-#ifndef CLEARPAD3000_RESET_GPIO
-#define CLEARPAD3000_RESET_GPIO (26)
-#endif
-
-static int synaptics_touchpad_setup(void);
-
-static struct msm_gpio clearpad3000_cfg_data[] = {
-	{GPIO_CFG(CLEARPAD3000_ATTEN_GPIO, 0, GPIO_CFG_INPUT,
-			GPIO_CFG_NO_PULL, GPIO_CFG_6MA), "rmi4_attn"},
-	{GPIO_CFG(CLEARPAD3000_RESET_GPIO, 0, GPIO_CFG_OUTPUT,
-			GPIO_CFG_PULL_DOWN, GPIO_CFG_8MA), "rmi4_reset"},
-};
-
-static struct rmi_XY_pair rmi_offset = {.x = 0, .y = 0};
-static struct rmi_range rmi_clipx = {.min = 48, .max = 980};
-static struct rmi_range rmi_clipy = {.min = 7, .max = 1647};
-static struct rmi_f11_functiondata synaptics_f11_data = {
-	.swap_axes = false,
-	.flipX = false,
-	.flipY = false,
-	.offset = &rmi_offset,
-	.button_height = 113,
-	.clipX = &rmi_clipx,
-	.clipY = &rmi_clipy,
-};
-
-#define MAX_LEN		100
-
-static ssize_t clearpad3000_virtual_keys_register(struct kobject *kobj,
-		     struct kobj_attribute *attr, char *buf)
-{
-	char *virtual_keys = __stringify(EV_KEY) ":" __stringify(KEY_MENU) \
-			     ":60:830:120:60" ":" __stringify(EV_KEY) \
-			     ":" __stringify(KEY_HOME)   ":180:830:120:60" \
-				":" __stringify(EV_KEY) ":" \
-				__stringify(KEY_SEARCH) ":300:830:120:60" \
-				":" __stringify(EV_KEY) ":" \
-			__stringify(KEY_BACK)   ":420:830:120:60" "\n";
-
-	return snprintf(buf, strnlen(virtual_keys, MAX_LEN) + 1 , "%s",
-			virtual_keys);
-}
-
-static struct kobj_attribute clearpad3000_virtual_keys_attr = {
-	.attr = {
-		.name = "virtualkeys.sensor00fn11",
-		.mode = S_IRUGO,
-	},
-	.show = &clearpad3000_virtual_keys_register,
-};
-
-static struct attribute *virtual_key_properties_attrs[] = {
-	&clearpad3000_virtual_keys_attr.attr,
-	NULL
-};
-
-static struct attribute_group virtual_key_properties_attr_group = {
-	.attrs = virtual_key_properties_attrs,
-};
-
-struct kobject *virtual_key_properties_kobj;
-
-static struct rmi_functiondata synaptics_functiondata[] = {
-	{
-		.function_index = RMI_F11_INDEX,
-		.data = &synaptics_f11_data,
-	},
-};
-
-static struct rmi_functiondata_list synaptics_perfunctiondata = {
-	.count = ARRAY_SIZE(synaptics_functiondata),
-	.functiondata = synaptics_functiondata,
-};
-
-static struct rmi_sensordata synaptics_sensordata = {
-	.perfunctiondata = &synaptics_perfunctiondata,
-	.rmi_sensor_setup	= synaptics_touchpad_setup,
-};
-
-static struct rmi_i2c_platformdata synaptics_platformdata = {
-	.i2c_address = 0x2c,
-	.irq_type = IORESOURCE_IRQ_LOWLEVEL,
-	.sensordata = &synaptics_sensordata,
-};
-
-static struct i2c_board_info synaptic_i2c_clearpad3k[] = {
-	{
-	I2C_BOARD_INFO("rmi4_ts", 0x2c),
-	.platform_data = &synaptics_platformdata,
-	},
-};
-
-static int synaptics_touchpad_setup(void)
-{
-	int retval = 0;
-
-	virtual_key_properties_kobj =
-		kobject_create_and_add("board_properties", NULL);
-	if (virtual_key_properties_kobj)
-		retval = sysfs_create_group(virtual_key_properties_kobj,
-				&virtual_key_properties_attr_group);
-	if (!virtual_key_properties_kobj || retval)
-		pr_err("failed to create ft5202 board_properties\n");
-
-	retval = msm_gpios_request_enable(clearpad3000_cfg_data,
-		    sizeof(clearpad3000_cfg_data)/sizeof(struct msm_gpio));
-	if (retval) {
-		pr_err("%s:Failed to obtain touchpad GPIO %d. Code: %d.",
-				__func__, CLEARPAD3000_ATTEN_GPIO, retval);
-		retval = 0; /* ignore the err */
-	}
-	synaptics_platformdata.irq = gpio_to_irq(CLEARPAD3000_ATTEN_GPIO);
-
-	gpio_set_value(CLEARPAD3000_RESET_GPIO, 0);
-	usleep(10000);
-	gpio_set_value(CLEARPAD3000_RESET_GPIO, 1);
-	usleep(50000);
-
-	return retval;
-}
-#endif
-
-#define FT5X06_IRQ_GPIO		48
-#define FT5X06_RESET_GPIO	26
-
-static ssize_t
-ft5x06_virtual_keys_register(struct kobject *kobj,
-			     struct kobj_attribute *attr,
-			     char *buf)
-{
-	return snprintf(buf, 200,
-	__stringify(EV_KEY) ":" __stringify(KEY_MENU)  ":40:510:80:60"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_HOME)   ":120:510:80:60"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":200:510:80:60"
-	":" __stringify(EV_KEY) ":" __stringify(KEY_BACK)   ":280:510:80:60"
-	"\n");
-}
-
-static struct kobj_attribute ft5x06_virtual_keys_attr = {
-	.attr = {
-		.name = "virtualkeys.ft5x06_ts",
-		.mode = S_IRUGO,
-	},
-	.show = &ft5x06_virtual_keys_register,
-};
-
-static struct attribute *ft5x06_virtual_key_properties_attrs[] = {
-	&ft5x06_virtual_keys_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ft5x06_virtual_key_properties_attr_group = {
-	.attrs = ft5x06_virtual_key_properties_attrs,
-};
-
-struct kobject *ft5x06_virtual_key_properties_kobj;
-
-static struct ft5x06_ts_platform_data ft5x06_platformdata = {
-	.x_max		= 320,
-	.y_max		= 480,
-	.reset_gpio	= FT5X06_RESET_GPIO,
-	.irq_gpio	= FT5X06_IRQ_GPIO,
-	.irqflags	= IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-};
-
-static struct i2c_board_info ft5x06_device_info[] __initdata = {
-	{
-		I2C_BOARD_INFO("ft5x06_ts", 0x38),
-		.platform_data = &ft5x06_platformdata,
-		.irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO),
-	},
-};
-
-static void ft5x06_touchpad_setup(void)
-{
-	int rc;
-
-	rc = gpio_tlmm_config(GPIO_CFG(FT5X06_IRQ_GPIO, 0,
-			GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
-			GPIO_CFG_8MA), GPIO_CFG_ENABLE);
-	if (rc)
-		pr_err("%s: gpio_tlmm_config for %d failed\n",
-			__func__, FT5X06_IRQ_GPIO);
-
-	rc = gpio_tlmm_config(GPIO_CFG(FT5X06_RESET_GPIO, 0,
-			GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
-			GPIO_CFG_8MA), GPIO_CFG_ENABLE);
-	if (rc)
-		pr_err("%s: gpio_tlmm_config for %d failed\n",
-			__func__, FT5X06_RESET_GPIO);
-
-	ft5x06_virtual_key_properties_kobj =
-			kobject_create_and_add("board_properties", NULL);
-
-	if (ft5x06_virtual_key_properties_kobj)
-		rc = sysfs_create_group(ft5x06_virtual_key_properties_kobj,
-				&ft5x06_virtual_key_properties_attr_group);
-
-	if (!ft5x06_virtual_key_properties_kobj || rc)
-		pr_err("%s: failed to create board_properties\n", __func__);
-
-	i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
-				ft5x06_device_info,
-				ARRAY_SIZE(ft5x06_device_info));
-}
-
 static struct android_usb_platform_data android_usb_pdata = {
 	.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
 };
@@ -924,7 +711,7 @@
 {
 	reserve_info = &msm7627a_reserve_info;
 	msm_reserve();
-	msm_pm_8625_boot_pdata.p_addr = memblock_alloc(SZ_8, SZ_64K);
+	memblock_remove(MSM8625_WARM_BOOT_PHYS, SZ_32);
 }
 
 static void __init msm8625_reserve(void)
@@ -970,19 +757,6 @@
 					= &msm_gsbi1_qup_i2c_pdata;
 }
 
-static struct msm_handset_platform_data hs_platform_data = {
-	.hs_name = "7k_handset",
-	.pwr_key_delay_ms = 500, /* 0 will disable end key */
-};
-
-static struct platform_device hs_pdev = {
-	.name   = "msm-handset",
-	.id     = -1,
-	.dev    = {
-		.platform_data = &hs_platform_data,
-	},
-};
-
 static struct platform_device msm_proccomm_regulator_dev = {
 	.name   = PROCCOMM_REGULATOR_DEV_NAME,
 	.id     = -1,
@@ -999,231 +773,6 @@
 				__func__, rc);
 }
 
-/* 8625 keypad device information */
-static unsigned int kp_row_gpios_8625[] = {31};
-static unsigned int kp_col_gpios_8625[] = {36, 37};
-
-static const unsigned short keymap_8625[] = {
-	KEY_VOLUMEUP,
-	KEY_VOLUMEDOWN,
-};
-
-static struct gpio_event_matrix_info kp_matrix_info_8625 = {
-	.info.func      = gpio_event_matrix_func,
-	.keymap         = keymap_8625,
-	.output_gpios   = kp_row_gpios_8625,
-	.input_gpios    = kp_col_gpios_8625,
-	.noutputs       = ARRAY_SIZE(kp_row_gpios_8625),
-	.ninputs        = ARRAY_SIZE(kp_col_gpios_8625),
-	.settle_time.tv_nsec = 40 * NSEC_PER_USEC,
-	.poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
-	.flags          = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
-			  GPIOKPF_PRINT_UNMAPPED_KEYS,
-};
-
-static struct gpio_event_info *kp_info_8625[] = {
-	&kp_matrix_info_8625.info,
-};
-static struct gpio_event_platform_data kp_pdata_8625 = {
-	.name           = "8625_kp",
-	.info           = kp_info_8625,
-	.info_count     = ARRAY_SIZE(kp_info_8625)
-};
-
-static struct platform_device kp_pdev_8625 = {
-	.name   = GPIO_EVENT_DEV_NAME,
-	.id     = -1,
-	.dev    = {
-		.platform_data  = &kp_pdata_8625,
-	},
-};
-
-#define LED_RED_GPIO_8625 49
-#define LED_GREEN_GPIO_8625 34
-
-static struct gpio_led gpio_leds_config_8625[] = {
-	{
-		.name = "green",
-		.gpio = LED_GREEN_GPIO_8625,
-	},
-	{
-		.name = "red",
-		.gpio = LED_RED_GPIO_8625,
-	},
-};
-
-static struct gpio_led_platform_data gpio_leds_pdata_8625 = {
-	.num_leds = ARRAY_SIZE(gpio_leds_config_8625),
-	.leds = gpio_leds_config_8625,
-};
-
-static struct platform_device gpio_leds_8625 = {
-	.name          = "leds-gpio",
-	.id            = -1,
-	.dev           = {
-		.platform_data = &gpio_leds_pdata_8625,
-	},
-};
-
-#define MXT_TS_IRQ_GPIO         48
-#define MXT_TS_RESET_GPIO       26
-
-static const u8 mxt_config_data[] = {
-	/* T6 Object */
-	0, 0, 0, 0, 0, 0,
-	/* T38 Object */
-	16, 0, 0, 0, 0, 0, 0, 0,
-	/* T7 Object */
-	32, 16, 50,
-	/* T8 Object */
-	30, 0, 20, 20, 0, 0, 20, 0, 50, 0,
-	/* T9 Object */
-	3, 0, 0, 18, 11, 0, 32, 75, 3, 3,
-	0, 1, 1, 0, 10, 10, 10, 10, 31, 3,
-	223, 1, 11, 11, 15, 15, 151, 43, 145, 80,
-	100, 15, 0, 0, 0,
-	/* T15 Object */
-	131, 0, 11, 11, 1, 1, 0, 45, 3, 0,
-	0,
-	/* T18 Object */
-	0, 0,
-	/* T19 Object */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0,
-	/* T23 Object */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0,
-	/* T25 Object */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0,
-	/* T40 Object */
-	0, 0, 0, 0, 0,
-	/* T42 Object */
-	0, 0, 0, 0, 0, 0, 0, 0,
-	/* T46 Object */
-	0, 2, 32, 48, 0, 0, 0, 0, 0,
-	/* T47 Object */
-	1, 20, 60, 5, 2, 50, 40, 0, 0, 40,
-	/* T48 Object */
-	1, 12, 80, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
-	10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
-	0, 0, 0, 0, 16, 65, 3, 1, 1, 0,
-	10, 10, 10, 0, 0, 15, 15, 154, 58, 145,
-	80, 100, 15, 3,
-};
-
-static struct mxt_config_info mxt_config_array[] = {
-	{
-		.config		= mxt_config_data,
-		.config_length	= ARRAY_SIZE(mxt_config_data),
-		.family_id	= 0x81,
-		.variant_id	= 0x01,
-		.version	= 0x10,
-		.build		= 0xAA,
-	},
-};
-
-static int mxt_key_codes[MXT_KEYARRAY_MAX_KEYS] = {
-	[0] = KEY_HOME,
-	[1] = KEY_MENU,
-	[9] = KEY_BACK,
-	[10] = KEY_SEARCH,
-};
-
-static struct mxt_platform_data mxt_platform_data = {
-	.config_array		= mxt_config_array,
-	.config_array_size	= ARRAY_SIZE(mxt_config_array),
-	.panel_minx		= 0,
-	.panel_maxx		= 479,
-	.panel_miny		= 0,
-	.panel_maxy		= 799,
-	.disp_minx		= 0,
-	.disp_maxx		= 479,
-	.disp_miny		= 0,
-	.disp_maxy		= 799,
-	.irqflags               = IRQF_TRIGGER_FALLING,
-	.i2c_pull_up            = true,
-	.reset_gpio		= MXT_TS_RESET_GPIO,
-	.irq_gpio		= MXT_TS_IRQ_GPIO,
-	.key_codes		= mxt_key_codes,
-};
-
-static struct i2c_board_info mxt_device_info[] __initdata = {
-	{
-		I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
-		.platform_data = &mxt_platform_data,
-		.irq = MSM_GPIO_TO_INT(MXT_TS_IRQ_GPIO),
-	},
-};
-
-static void msm7627a_add_io_devices(void)
-{
-	int rc;
-
-	/* touchscreen */
-	if (machine_is_msm7627a_qrd1()) {
-		i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
-					synaptic_i2c_clearpad3k,
-					ARRAY_SIZE(synaptic_i2c_clearpad3k));
-	} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
-		rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_IRQ_GPIO, 0,
-				GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
-				GPIO_CFG_8MA), GPIO_CFG_ENABLE);
-		if (rc) {
-			pr_err("%s: gpio_tlmm_config for %d failed\n",
-				__func__, MXT_TS_IRQ_GPIO);
-		}
-
-		rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_RESET_GPIO, 0,
-				GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
-				GPIO_CFG_8MA), GPIO_CFG_ENABLE);
-		if (rc) {
-			pr_err("%s: gpio_tlmm_config for %d failed\n",
-				__func__, MXT_TS_RESET_GPIO);
-		}
-
-		i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
-					mxt_device_info,
-					ARRAY_SIZE(mxt_device_info));
-	} else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
-		ft5x06_touchpad_setup();
-	}
-
-	/* headset */
-	platform_device_register(&hs_pdev);
-
-	/* vibrator */
-#ifdef CONFIG_MSM_RPC_VIBRATOR
-	msm_init_pmic_vibrator();
-#endif
-
-	/* keypad */
-	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
-		platform_device_register(&kp_pdev_8625);
-
-	/* leds */
-	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
-		rc = gpio_tlmm_config(GPIO_CFG(LED_RED_GPIO_8625, 0,
-				GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
-				GPIO_CFG_16MA), GPIO_CFG_ENABLE);
-		if (rc) {
-			pr_err("%s: gpio_tlmm_config for %d failed\n",
-				__func__, LED_RED_GPIO_8625);
-		}
-
-		rc = gpio_tlmm_config(GPIO_CFG(LED_GREEN_GPIO_8625, 0,
-				GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
-				GPIO_CFG_16MA), GPIO_CFG_ENABLE);
-		if (rc) {
-			pr_err("%s: gpio_tlmm_config for %d failed\n",
-				__func__, LED_GREEN_GPIO_8625);
-		}
-
-		platform_device_register(&gpio_leds_8625);
-	}
-}
-
 static int __init msm_qrd_init_ar6000pm(void)
 {
 	msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
@@ -1337,7 +886,7 @@
 #endif
 
 	msm7627a_camera_init();
-	msm7627a_add_io_devices();
+	qrd7627a_add_io_devices();
 	msm7x25a_kgsl_3d0_init();
 }
 
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 3421bc1..67d5618 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -3350,6 +3350,7 @@
 	F_GFX3D(145455000, pll2,  2, 11),
 	F_GFX3D(160000000, pll2,  1,  5),
 	F_GFX3D(177778000, pll2,  2,  9),
+	F_GFX3D(192000000, pll8,  1,  2),
 	F_GFX3D(200000000, pll2,  1,  4),
 	F_GFX3D(228571000, pll2,  2,  7),
 	F_GFX3D(266667000, pll2,  1,  3),
@@ -3367,7 +3368,7 @@
 };
 
 static unsigned long fmax_gfx3d_8930[MAX_VDD_LEVELS] __initdata = {
-	[VDD_DIG_LOW]     = 128000000,
+	[VDD_DIG_LOW]     = 192000000,
 	[VDD_DIG_NOMINAL] = 320000000,
 	[VDD_DIG_HIGH]    = 450000000
 };
@@ -4902,7 +4903,6 @@
 static struct clk_lookup msm_clocks_8064[] = {
 	CLK_LOOKUP("xo",		cxo_a_clk.c,	""),
 	CLK_LOOKUP("xo",		pxo_a_clk.c,	""),
-	CLK_LOOKUP("xo",		cxo_clk.c,	"msm_otg"),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"pil_riva"),
 	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_qdsp6v4.0"),
@@ -5070,7 +5070,7 @@
 	CLK_LOOKUP("tv_clk",		mdp_tv_clk.c,	"footswitch-8x60.4"),
 	CLK_LOOKUP("hdmi_clk",		hdmi_tv_clk.c,		NULL),
 	CLK_LOOKUP("core_clk",		hdmi_app_clk.c,		"hdmi_msm.1"),
-	CLK_LOOKUP("vpe_clk",		vpe_clk.c,		""),
+	CLK_LOOKUP("vpe_clk",		vpe_clk.c,		"msm_vpe.0"),
 	CLK_LOOKUP("core_clk",		vpe_clk.c,	"footswitch-8x60.9"),
 	CLK_LOOKUP("vfe_clk",		vfe_clk.c,		"msm_vfe.0"),
 	CLK_LOOKUP("core_clk",		vfe_clk.c,	"footswitch-8x60.8"),
@@ -5188,7 +5188,6 @@
 static struct clk_lookup msm_clocks_8960[] = {
 	CLK_LOOKUP("xo",		cxo_a_clk.c,	""),
 	CLK_LOOKUP("xo",		pxo_a_clk.c,	""),
-	CLK_LOOKUP("xo",		cxo_clk.c,	"msm_otg"),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"pil_riva"),
 	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_qdsp6v4.0"),
@@ -5982,6 +5981,19 @@
 		if (!readl_relaxed(PRNG_CLK_NS_REG))
 			writel_relaxed(0x2B, PRNG_CLK_NS_REG);
 	}
+
+	/*
+	 * Program PLL15 to 900MHz with ref clk = 27MHz and
+	 * only enable PLL main output.
+	 */
+	if (cpu_is_msm8930()) {
+		writel_relaxed(0x30021, MM_PLL3_L_VAL_REG);
+		writel_relaxed(0x1,	MM_PLL3_M_VAL_REG);
+		writel_relaxed(0x3,	MM_PLL3_N_VAL_REG);
+
+		writel_relaxed(0xC20000, MM_PLL3_CONFIG_REG);
+		writel_relaxed(0,	 MM_PLL3_TEST_CTL_REG);
+	}
 }
 
 /* Local clock driver initialization. */
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 6f02b75..cc71c0b 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1600,7 +1600,6 @@
 
 static struct clk_lookup msm_clocks_9615[] = {
 	CLK_LOOKUP("xo",	cxo_a_clk.c,	""),
-	CLK_LOOKUP("xo",	cxo_clk.c,	"msm_otg"),
 	CLK_LOOKUP("xo",	cxo_clk.c,	"BAM_RMNT"),
 	CLK_LOOKUP("xo",	cxo_clk.c,	"msm_xo"),
 	CLK_LOOKUP("pll0",	pll0_clk.c,	NULL),
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index c45a137..b03f137 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -953,6 +953,12 @@
 	.id = -1,
 };
 
+struct platform_device msm_pil_dsps = {
+	.name          = "pil_dsps",
+	.id            = -1,
+	.dev.platform_data = "dsps",
+};
+
 static struct resource smd_resource[] = {
 	{
 		.name   = "a9_m2a_0",
@@ -1101,7 +1107,6 @@
 	.smd_ssr_config = &smd_ssr_config,
 };
 
-
 struct platform_device msm_device_smd = {
 	.name		= "msm_smd",
 	.id		= -1,
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index bb0d9b9..1acc833 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -428,7 +428,7 @@
  * Machine specific data for AUX PCM Interface
  * which the driver will  be unware of.
  */
-struct msm_dai_auxpcm_pdata auxpcm_rx_pdata = {
+struct msm_dai_auxpcm_pdata auxpcm_pdata = {
 	.clk = "pcm_clk",
 	.mode = AFE_PCM_CFG_MODE_PCM,
 	.sync = AFE_PCM_CFG_SYNC_INT,
@@ -443,13 +443,16 @@
 	.name = "msm-dai-q6",
 	.id = 2,
 	.dev = {
-		.platform_data = &auxpcm_rx_pdata,
+		.platform_data = &auxpcm_pdata,
 	},
 };
 
 struct platform_device msm_cpudai_auxpcm_tx = {
 	.name = "msm-dai-q6",
 	.id = 3,
+	.dev = {
+		.platform_data = &auxpcm_pdata,
+	},
 };
 
 struct platform_device msm_cpu_fe = {
diff --git a/arch/arm/mach-msm/devices-fsm9xxx.c b/arch/arm/mach-msm/devices-fsm9xxx.c
index d46e4d6..777b6d6 100644
--- a/arch/arm/mach-msm/devices-fsm9xxx.c
+++ b/arch/arm/mach-msm/devices-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -22,6 +22,7 @@
 #include "devices.h"
 #include "smd_private.h"
 #include "clock-local.h"
+#include "msm_watchdog.h"
 
 #include <asm/mach/flash.h>
 #include <asm/mach/mmc.h>
@@ -389,3 +390,22 @@
 	.id     = -1,
 };
 
+/*
+ * Watchdog
+ */
+
+static struct msm_watchdog_pdata fsm_watchdog_pdata = {
+	.pet_time = 10000,
+	.bark_time = 11000,
+	.has_secure = false,
+	.has_vic = true,
+};
+
+struct platform_device fsm9xxx_device_watchdog = {
+	.name = "msm_watchdog",
+	.id = -1,
+	.dev = {
+		.platform_data = &fsm_watchdog_pdata,
+	},
+};
+
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index ae90301..3ad3ee4 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -220,6 +220,12 @@
 	.id = -1,
 };
 
+struct platform_device msm_pil_dsps = {
+	.name          = "pil_dsps",
+	.id            = -1,
+	.dev.platform_data = "dsps",
+};
+
 static struct resource msm_uart1_dm_resources[] = {
 	{
 		.start = MSM_UART1DM_PHYS,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 1c5f397..ac9feee 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -217,6 +217,7 @@
 extern struct platform_device msm_pil_q6v3;
 extern struct platform_device msm_pil_modem;
 extern struct platform_device msm_pil_tzapps;
+extern struct platform_device msm_pil_dsps;
 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;
@@ -315,6 +316,7 @@
 extern struct platform_device msm8660_device_watchdog;
 extern struct platform_device msm8064_device_watchdog;
 extern struct platform_device msm9615_device_watchdog;
+extern struct platform_device fsm9xxx_device_watchdog;
 
 extern struct platform_device msm_etb_device;
 extern struct platform_device msm_tpiu_device;
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 4609a4b..d5a1d3f 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -653,7 +653,8 @@
 	regval &= ~RETENTION_BIT;
 	writel_relaxed(regval, fs->gfs_ctl_reg);
 
-	fs->rdev = regulator_register(&fs->desc, &pdev->dev, init_data, fs);
+	fs->rdev = regulator_register(&fs->desc, &pdev->dev,
+							init_data, fs, NULL);
 	if (IS_ERR(footswitches[pdev->id].rdev)) {
 		pr_err("regulator_register(\"%s\") failed\n",
 			fs->desc.name);
diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c
index 673253b..73cbab1 100644
--- a/arch/arm/mach-msm/footswitch-pcom.c
+++ b/arch/arm/mach-msm/footswitch-pcom.c
@@ -266,7 +266,8 @@
 	if (rc)
 		return rc;
 
-	fs->rdev = regulator_register(&fs->desc, &pdev->dev, init_data, fs);
+	fs->rdev = regulator_register(&fs->desc, &pdev->dev,
+							init_data, fs, NULL);
 	if (IS_ERR(fs->rdev)) {
 		pr_err("regulator_register(%s) failed\n", fs->desc.name);
 		rc = PTR_ERR(fs->rdev);
diff --git a/arch/arm/mach-msm/gss-8064.c b/arch/arm/mach-msm/gss-8064.c
index 1ddb7a3..3c475d6 100644
--- a/arch/arm/mach-msm/gss-8064.c
+++ b/arch/arm/mach-msm/gss-8064.c
@@ -113,7 +113,7 @@
 
 /* FIXME: Get address, size from PIL */
 static struct ramdump_segment gss_segments[] = {
-	{0x89D00000 - 0x89000000}
+	{0x89000000, 0x00D00000}
 };
 
 static struct ramdump_segment smem_segments[] = {
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index 32d162d..868054d 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -228,12 +228,11 @@
 	biceq	r3, r3, #0x400
 	mcreq	p15, 7, r3, c15, c0, 2
 #endif
-	stmfd   sp!, {lr}
-	bl      v7_flush_kern_cache_all
 #ifdef CONFIG_MSM_JTAG
+	stmfd   sp!, {lr}
 	bl      msm_jtag_restore_state
-#endif
 	ldmfd   sp!, {lr}
+#endif
 	mov     r0, #1
 	bx      lr
 	nop
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index ae4d632..7b74f1e 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -172,6 +172,11 @@
 	BACK_CAMERA_INT_3D,
 };
 
+enum msm_sensor_type {
+	BAYER_SENSOR,
+	YUV_SENSOR,
+};
+
 enum camera_vreg_type {
 	REG_LDO,
 	REG_VS,
@@ -261,6 +266,7 @@
 	struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
 	char *eeprom_data;
 	enum msm_camera_type camera_type;
+	enum msm_sensor_type sensor_type;
 	struct msm_actuator_info *actuator_info;
 	int pmic_gpio_enable;
 };
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 2aae5dd..ba038cb 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -493,8 +493,6 @@
 	unsigned long len;
 	struct file *file;
 	struct msm_pmem_info info;
-	struct msm_mapped_buffer *msm_buffer;
-	int subsys_id;
 	struct ion_handle *handle;
 };
 
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index af9213f..c17795a 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -15,9 +15,9 @@
 
 enum {
 	VIDEO_DOMAIN,
-	CAMERA_DOMAIN = VIDEO_DOMAIN,
-	DISPLAY_DOMAIN = CAMERA_DOMAIN,
-	ROTATOR_DOMAIN = DISPLAY_DOMAIN,
+	CAMERA_DOMAIN,
+	DISPLAY_DOMAIN,
+	ROTATOR_DOMAIN,
 	MAX_DOMAINS
 };
 
diff --git a/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h b/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
index a0ec244..721db1d 100644
--- a/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/irqs-fsm9xxx.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -86,6 +86,7 @@
 #define INT_ADSP_A11		INT_Q6_SW_IRQ_0
 #define INT_ADSP_A11_SMSM	INT_ADSP_A11
 #define INT_SIRC_0		INT_PERPH_SUPSS_IRQ
+#define WDT0_ACCSCSSNBARK_INT	INT_WDT0_ACCSCSSBARK
 
 #define NR_MSM_IRQS		128
 #define NR_GPIO_IRQS		0
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 8f5d673..34af610 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -51,6 +51,8 @@
 #define MSM_DEBUG_UART_PHYS	CONFIG_MSM_DEBUG_UART_PHYS
 #endif
 
+#define MSM8625_WARM_BOOT_PHYS  0x0FD00000
+
 
 #if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
 	defined(CONFIG_ARCH_MSM8930) || defined(CONFIG_ARCH_MSM9615) || \
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index 34729b3..9b72f7c 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -51,7 +51,12 @@
 #define SPS_IOVEC_FLAG_INT  0x8000  /* Generate interrupt */
 #define SPS_IOVEC_FLAG_EOT  0x4000  /* Generate end-of-transfer indication */
 #define SPS_IOVEC_FLAG_EOB  0x2000  /* Generate end-of-block indication */
-#define SPS_IOVEC_FLAG_NO_SUBMIT 0x0100  /* Do not submit descriptor to HW */
+#define SPS_IOVEC_FLAG_NWD  0x1000  /* notify when done */
+#define SPS_IOVEC_FLAG_CMD  0x0800  /* command descriptor */
+#define SPS_IOVEC_FLAG_LOCK  0x0400  /* pipe lock */
+#define SPS_IOVEC_FLAG_UNLOCK  0x0200  /* pipe unlock */
+#define SPS_IOVEC_FLAG_IMME 0x0100  /* immediate command descriptor */
+#define SPS_IOVEC_FLAG_NO_SUBMIT 0x0002  /* Do not submit descriptor to HW */
 #define SPS_IOVEC_FLAG_DEFAULT   0x0001  /* Use driver default */
 
 /* BAM device options flags */
@@ -127,6 +132,8 @@
 	SPS_O_STREAMING = 0x00010000,  /* Enable streaming mode (no EOT) */
 	/* Use MTI/SETPEND instead of BAM interrupt */
 	SPS_O_IRQ_MTI   = 0x00020000,
+	/* NWD bit written with EOT for BAM2BAM producer pipe */
+	SPS_O_WRITE_NWD   = 0x00040000,
 
 	/* Options to enable software features */
 	/* Transfer operation should be polled */
@@ -233,6 +240,14 @@
 /*   SPS_TIMER_MODE_PERIODIC,    Not supported by hardware yet */
 };
 
+/*
+ * This enum indicates the command type in a command element
+ */
+enum sps_command_type {
+	SPS_WRITE_COMMAND = 0,
+	SPS_READ_COMMAND,
+};
+
 /**
  * This data type corresponds to the native I/O vector (BAM descriptor)
  * supported by SPS hardware
@@ -248,6 +263,26 @@
 	u32 flags:16;
 };
 
+/**
+ * This data type corresponds to the native Command Element
+ * supported by SPS hardware
+ *
+ * @addr - register address.
+ * @command - command type.
+ * @data - for write command: content to be written into peripheral register.
+ *         for read command: dest addr to write peripheral register value to.
+ * @mask - register mask.
+ * @reserved - for future usage.
+ *
+ */
+struct sps_command_element {
+	u32 addr:24;
+	u32 command:8;
+	u32 data;
+	u32 mask;
+	u32 reserved;
+};
+
 /*
  * BAM device's security configuation
  */
@@ -398,6 +433,7 @@
  * @data - Data FIFO (BAM-to-BAM mode only).
  *
  * @event_thresh - Pipe event threshold or derivative.
+ * @lock_group - The lock group this pipe belongs to.
  *
  * @sps_reserved - Reserved word - client must not modify.
  *
@@ -419,6 +455,8 @@
 
 	u32 event_thresh;
 
+	u32 lock_group;
+
 	/* SETPEND/MTI interrupt generation parameters */
 
 	u32 irq_gen_addr;
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index a7663b6..1959f5d 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -13,6 +13,7 @@
 #include <mach/msm_subsystem_map.h>
 #include <linux/memory_alloc.h>
 #include <linux/iommu.h>
+#include <linux/vmalloc.h>
 #include <asm/sizes.h>
 #include <asm/page.h>
 #include <linux/init.h>
@@ -43,10 +44,145 @@
 	char *name;
 	int  domain;
 } msm_iommu_ctx_names[] = {
+	/* Camera */
+	{
+		.name = "vpe_src",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "vpe_dst",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "vfe_imgwr",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "vfe_misc",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "ijpeg_src",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "ijpeg_dst",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "jpegd_src",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Camera */
+	{
+		.name = "jpegd_dst",
+		.domain = CAMERA_DOMAIN,
+	},
+	/* Rotator */
+	{
+		.name = "rot_src",
+		.domain = ROTATOR_DOMAIN,
+	},
+	/* Rotator */
+	{
+		.name = "rot_dst",
+		.domain = ROTATOR_DOMAIN,
+	},
+	/* Video */
+	{
+		.name = "vcodec_a_mm1",
+		.domain = VIDEO_DOMAIN,
+	},
+	/* Video */
+	{
+		.name = "vcodec_b_mm2",
+		.domain = VIDEO_DOMAIN,
+	},
+	/* Video */
+	{
+		.name = "vcodec_a_stream",
+		.domain = VIDEO_DOMAIN,
+	},
 };
 
+static struct mem_pool video_pools[] =  {
+	/*
+	 * Video hardware has the following requirements:
+	 * 1. All video addresses used by the video hardware must be at a higher
+	 *    address than video firmware address.
+	 * 2. Video hardware can only access a range of 256MB from the base of
+	 *    the video firmware.
+	*/
+	[VIDEO_FIRMWARE_POOL] =
+	/* Low addresses, intended for video firmware */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_16M - SZ_128K,
+		},
+	[VIDEO_MAIN_POOL] =
+	/* Main video pool */
+		{
+			.paddr	= SZ_16M,
+			.size	= SZ_256M - SZ_16M,
+		},
+	[GEN_POOL] =
+	/* Remaining address space up to 2G */
+		{
+			.paddr	= SZ_256M,
+			.size	= SZ_2G - SZ_256M,
+		},
+};
+
+static struct mem_pool camera_pools[] =  {
+	[GEN_POOL] =
+	/* One address space for camera */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_2G - SZ_128K,
+		},
+};
+
+static struct mem_pool display_pools[] =  {
+	[GEN_POOL] =
+	/* One address space for display */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_2G - SZ_128K,
+		},
+};
+
+static struct mem_pool rotator_pools[] =  {
+	[GEN_POOL] =
+	/* One address space for rotator */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_2G - SZ_128K,
+		},
+};
 
 static struct msm_iommu_domain msm_iommu_domains[] = {
+		[VIDEO_DOMAIN] = {
+			.iova_pools = video_pools,
+			.npools = ARRAY_SIZE(video_pools),
+		},
+		[CAMERA_DOMAIN] = {
+			.iova_pools = camera_pools,
+			.npools = ARRAY_SIZE(camera_pools),
+		},
+		[DISPLAY_DOMAIN] = {
+			.iova_pools = display_pools,
+			.npools = ARRAY_SIZE(display_pools),
+		},
+		[ROTATOR_DOMAIN] = {
+			.iova_pools = rotator_pools,
+			.npools = ARRAY_SIZE(rotator_pools),
+		},
 };
 
 int msm_iommu_map_extra(struct iommu_domain *domain,
@@ -54,33 +190,32 @@
 				unsigned long size,
 				int cached)
 {
-	int i, ret;
-	unsigned long temp_iova;
+	int i, ret = 0;
+	struct scatterlist *sglist;
+	unsigned int nrpages = PFN_ALIGN(size) >> PAGE_SHIFT;
+	struct page *dummy_page = phys_to_page(
+					PFN_ALIGN(virt_to_phys(iommu_dummy)));
 
-	for (i = size, temp_iova = start_iova; i > 0; i -= SZ_4K,
-						temp_iova += SZ_4K) {
-		ret = iommu_map(domain, temp_iova,
-				PFN_ALIGN(virt_to_phys(iommu_dummy)),
-				get_order(SZ_4K),
-				0);
-
-		if (ret) {
-			pr_err("%s: could not map %lx to dummy page in domain"
-				" %p\n",
-				__func__, temp_iova, domain);
-			goto out;
-		}
+	sglist = vmalloc(sizeof(*sglist) * nrpages);
+	if (!sglist) {
+		ret = -ENOMEM;
+		goto err1;
 	}
 
-	return 0;
+	sg_init_table(sglist, nrpages);
 
-out:
+	for (i = 0; i < nrpages; i++)
+		sg_set_page(&sglist[i], dummy_page, PAGE_SIZE, 0);
 
-	for ( ; i < size; i += SZ_4K, temp_iova -= SZ_4K)
-		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+	ret = iommu_map_range(domain, start_iova, sglist, size, cached);
+	if (ret) {
+		pr_err("%s: could not map extra %lx in domain %p\n",
+			__func__, start_iova, domain);
+	}
 
-	return -EINVAL;
-
+	vfree(sglist);
+err1:
+	return ret;
 }
 
 
@@ -181,8 +316,7 @@
 
 int msm_use_iommu()
 {
-	/* Kill use of the iommu by these clients for now. */
-	return 0;
+	return iommu_found();
 }
 
 static int __init msm_subsystem_iommu_init(void)
@@ -198,25 +332,29 @@
 			struct mem_pool *pool = &msm_iommu_domains[i].
 							iova_pools[j];
 			mutex_init(&pool->pool_mutex);
-			pool->gpool = gen_pool_create(PAGE_SHIFT, -1);
+			if (pool->size) {
+				pool->gpool = gen_pool_create(PAGE_SHIFT, -1);
 
-			if (!pool->gpool) {
-				pr_err("%s: domain %d: could not allocate iova"
-					" pool. iommu programming will not work"
-					" with iova space %d\n", __func__,
-					i, j);
-				continue;
-			}
+				if (!pool->gpool) {
+					pr_err("%s: could not allocate pool\n",
+						__func__);
+					pr_err("%s: domain %d iova space %d\n",
+						__func__, i, j);
+					continue;
+				}
 
-			if (gen_pool_add(pool->gpool, pool->paddr, pool->size,
-						-1)) {
-				pr_err("%s: domain %d: could not add memory to"
-					" iova pool. iommu programming will not"
-					" work with iova space %d\n", __func__,
-					i, j);
-				gen_pool_destroy(pool->gpool);
+				if (gen_pool_add(pool->gpool, pool->paddr,
+						pool->size, -1)) {
+					pr_err("%s: could not add memory\n",
+						__func__);
+					pr_err("%s: domain %d pool %d\n",
+						__func__, i, j);
+					gen_pool_destroy(pool->gpool);
+					pool->gpool = NULL;
+					continue;
+				}
+			} else {
 				pool->gpool = NULL;
-				continue;
 			}
 		}
 	}
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index 7e538b4..e0d2696 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -47,7 +47,7 @@
 #define MDM_MODEM_DELTA		100
 
 static int mdm_debug_on;
-static int first_power_on = 1;
+static int power_on_count;
 static int hsic_peripheral_status;
 static DEFINE_MUTEX(hsic_status_lock);
 
@@ -77,6 +77,16 @@
 
 static void power_on_mdm(struct mdm_modem_drv *mdm_drv)
 {
+	power_on_count++;
+
+	/* The second attempt to power-on the mdm is the first attempt
+	 * from user space, but we're already powered on. Ignore this.
+	 * Subsequent attempts are from SSR or if something failed, in
+	 * which case we must always reset the modem.
+	 */
+	if (power_on_count == 2)
+		return;
+
 	mdm_peripheral_disconnect(mdm_drv);
 
 	/* Pull RESET gpio low and wait for it to settle. */
@@ -84,7 +94,7 @@
 	gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 0);
 	usleep_range(5000, 10000);
 
-	/* Deassert RESET first and wait for ir to settle. */
+	/* Deassert RESET first and wait for it to settle. */
 	pr_debug("%s: Pulling RESET gpio high\n", __func__);
 	gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 1);
 	usleep(1000);
@@ -93,13 +103,12 @@
 	 * the first time the mdm is powered up.
 	 * Some targets do not use ap2mdm_kpdpwr_n_gpio.
 	 */
-	if (first_power_on) {
+	if (power_on_count == 1) {
 		if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0) {
 			pr_debug("%s: Powering on mdm modem\n", __func__);
 			gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
 			usleep(1000);
 		}
-		first_power_on = 0;
 	}
 	mdm_peripheral_connect(mdm_drv);
 
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 7fccf2e..a7ba4a0 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -42,6 +42,8 @@
 
 #define MDM_MODEM_TIMEOUT	6000
 #define MDM_MODEM_DELTA	100
+#define MDM_BOOT_TIMEOUT	60000L
+#define MDM_RDUMP_TIMEOUT	60000L
 
 static int mdm_debug_on;
 static struct workqueue_struct *mdm_queue;
@@ -250,8 +252,12 @@
 	mdm_drv->ops->power_on_mdm_cb(mdm_drv);
 	mdm_drv->boot_type = CHARM_NORMAL_BOOT;
 	complete(&mdm_needs_reload);
-	wait_for_completion(&mdm_boot);
-	pr_info("%s: mdm modem has been restarted\n", __func__);
+	if (!wait_for_completion_timeout(&mdm_boot,
+			msecs_to_jiffies(MDM_BOOT_TIMEOUT))) {
+		mdm_drv->mdm_boot_status = -ETIMEDOUT;
+		pr_info("%s: mdm modem restart timed out.\n", __func__);
+	} else
+		pr_info("%s: mdm modem has been restarted\n", __func__);
 	INIT_COMPLETION(mdm_boot);
 	return mdm_drv->mdm_boot_status;
 }
@@ -263,7 +269,14 @@
 	if (want_dumps) {
 		mdm_drv->boot_type = CHARM_RAM_DUMPS;
 		complete(&mdm_needs_reload);
-		wait_for_completion(&mdm_ram_dumps);
+		if (!wait_for_completion_timeout(&mdm_ram_dumps,
+				msecs_to_jiffies(MDM_RDUMP_TIMEOUT))) {
+			mdm_drv->mdm_ram_dump_status = -ETIMEDOUT;
+			pr_info("%s: mdm modem ramdumps timed out.\n",
+					__func__);
+		} else
+			pr_info("%s: mdm modem ramdumps completed.\n",
+					__func__);
 		INIT_COMPLETION(mdm_ram_dumps);
 		gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
 		mdm_drv->ops->power_down_mdm_cb(mdm_drv);
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 6f7f771..fa9159e 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -24,6 +24,9 @@
 #include <linux/suspend.h>
 #include <linux/rwsem.h>
 #include <linux/sysfs.h>
+#include <linux/workqueue.h>
+#include <linux/jiffies.h>
+#include <linux/wakelock.h>
 
 #include <asm/uaccess.h>
 #include <asm/setup.h>
@@ -51,6 +54,9 @@
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *dentry;
 #endif
+	struct delayed_work proxy;
+	struct wake_lock wlock;
+	char wake_name[32];
 };
 
 #define to_pil_device(d) container_of(d, struct pil_device, dev)
@@ -97,6 +103,30 @@
 	return dev ? to_pil_device(dev) : NULL;
 }
 
+static void pil_proxy_work(struct work_struct *work)
+{
+	struct pil_device *pil;
+
+	pil = container_of(work, struct pil_device, proxy.work);
+	pil->desc->ops->proxy_unvote(pil->desc);
+	wake_unlock(&pil->wlock);
+}
+
+static int pil_proxy_vote(struct pil_device *pil)
+{
+	if (pil->desc->ops->proxy_vote) {
+		wake_lock(&pil->wlock);
+		return pil->desc->ops->proxy_vote(pil->desc);
+	}
+	return 0;
+}
+
+static void pil_proxy_unvote(struct pil_device *pil, unsigned long timeout)
+{
+	if (pil->desc->ops->proxy_unvote)
+		schedule_delayed_work(&pil->proxy, msecs_to_jiffies(timeout));
+}
+
 #define IOMAP_SIZE SZ_4M
 
 static int load_segment(const struct elf32_phdr *phdr, unsigned num,
@@ -202,6 +232,7 @@
 	struct elf32_hdr *ehdr;
 	const struct elf32_phdr *phdr;
 	const struct firmware *fw;
+	unsigned long proxy_timeout = pil->desc->proxy_timeout;
 
 	down_read(&pil_pm_rwsem);
 	snprintf(fw_name, sizeof(fw_name), "%s.mdt", pil->desc->name);
@@ -255,13 +286,21 @@
 		}
 	}
 
+	ret = pil_proxy_vote(pil);
+	if (ret) {
+		dev_err(&pil->dev, "Failed to proxy vote\n");
+		goto release_fw;
+	}
+
 	ret = pil->desc->ops->auth_and_reset(pil->desc);
 	if (ret) {
 		dev_err(&pil->dev, "Failed to bring out of reset\n");
-		goto release_fw;
+		proxy_timeout = 0; /* Remove proxy vote immediately on error */
+		goto err_boot;
 	}
 	dev_info(&pil->dev, "brought %s out of reset\n", pil->desc->name);
-
+err_boot:
+	pil_proxy_unvote(pil, proxy_timeout);
 release_fw:
 	release_firmware(fw);
 out:
@@ -332,6 +371,13 @@
 }
 EXPORT_SYMBOL(pil_get);
 
+static void pil_shutdown(struct pil_device *pil)
+{
+	pil->desc->ops->shutdown(pil->desc);
+	flush_delayed_work(&pil->proxy);
+	pil_set_state(pil, PIL_OFFLINE);
+}
+
 /**
  * pil_put() - Inform PIL the peripheral no longer needs to be active
  * @peripheral_handle: pointer from a previous call to pil_get()
@@ -349,10 +395,8 @@
 	mutex_lock(&pil->lock);
 	if (WARN(!pil->count, "%s: Reference count mismatch\n", __func__))
 		goto err_out;
-	if (!--pil->count) {
-		pil->desc->ops->shutdown(pil->desc);
-		pil_set_state(pil, PIL_OFFLINE);
-	}
+	if (!--pil->count)
+		pil_shutdown(pil);
 	mutex_unlock(&pil->lock);
 
 	pil_d = find_peripheral(pil->desc->depends_on);
@@ -381,8 +425,7 @@
 
 	mutex_lock(&pil->lock);
 	if (!WARN(!pil->count, "%s: Reference count mismatch\n", __func__))
-		pil->desc->ops->shutdown(pil->desc);
-	pil_set_state(pil, PIL_OFFLINE);
+		pil_shutdown(pil);
 	mutex_unlock(&pil->lock);
 
 	put_device(&pil->dev);
@@ -502,8 +545,7 @@
 
 static int __msm_pil_shutdown(struct device *dev, void *data)
 {
-	struct pil_device *pil = to_pil_device(dev);
-	pil->desc->ops->shutdown(pil->desc);
+	pil_shutdown(to_pil_device(dev));
 	return 0;
 }
 
@@ -516,6 +558,7 @@
 static void pil_device_release(struct device *dev)
 {
 	struct pil_device *pil = to_pil_device(dev);
+	wake_lock_destroy(&pil->wlock);
 	mutex_destroy(&pil->lock);
 	kfree(pil);
 }
@@ -524,8 +567,14 @@
 {
 	int err;
 	static atomic_t pil_count = ATOMIC_INIT(-1);
-	struct pil_device *pil = kzalloc(sizeof(*pil), GFP_KERNEL);
+	struct pil_device *pil;
 
+	/* Ignore users who don't make any sense */
+	if (WARN(desc->ops->proxy_unvote && !desc->ops->proxy_vote,
+				"invalid proxy voting. ignoring\n"))
+		((struct pil_reset_ops *)desc->ops)->proxy_unvote = NULL;
+
+	pil = kzalloc(sizeof(*pil), GFP_KERNEL);
 	if (!pil)
 		return ERR_PTR(-ENOMEM);
 
@@ -536,10 +585,15 @@
 	pil->dev.bus = &pil_bus_type;
 	pil->dev.release = pil_device_release;
 
+	snprintf(pil->wake_name, sizeof(pil->wake_name), "pil-%s", desc->name);
+	wake_lock_init(&pil->wlock, WAKE_LOCK_SUSPEND, pil->wake_name);
+	INIT_DELAYED_WORK(&pil->proxy, pil_proxy_work);
+
 	dev_set_name(&pil->dev, "pil%d", atomic_inc_return(&pil_count));
 	err = device_register(&pil->dev);
 	if (err) {
 		put_device(&pil->dev);
+		wake_lock_destroy(&pil->wlock);
 		mutex_destroy(&pil->lock);
 		kfree(pil);
 		return ERR_PTR(err);
@@ -563,6 +617,7 @@
 	if (get_device(&pil->dev)) {
 		mutex_lock(&pil->lock);
 		WARN_ON(pil->count);
+		flush_delayed_work_sync(&pil->proxy);
 		msm_pil_debugfs_remove(pil);
 		device_unregister(&pil->dev);
 		mutex_unlock(&pil->lock);
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index cc00446..e3b250b 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -15,19 +15,41 @@
 struct device;
 struct module;
 
+/**
+ * struct pil_desc - PIL descriptor
+ * @name: string used for pil_get()
+ * @depends_on: booted before this peripheral
+ * @dev: parent device
+ * @ops: callback functions
+ * @owner: module the descriptor belongs to
+ * @proxy_timeout: delay in ms until proxy vote is removed
+ */
 struct pil_desc {
 	const char *name;
 	const char *depends_on;
 	struct device *dev;
 	const struct pil_reset_ops *ops;
 	struct module *owner;
+	unsigned long proxy_timeout;
 };
 
+/**
+ * struct pil_reset_ops - PIL operations
+ * @init_image: prepare an image for authentication
+ * @verify_blob: authenticate a program segment, called once for each loadable
+ *		 program segment (optional)
+ * @proxy_vote: make proxy votes before auth_and_reset (optional)
+ * @auth_and_reset: boot the processor
+ * @proxy_unvote: remove any proxy votes (optional)
+ * @shutdown: shutdown the processor
+ */
 struct pil_reset_ops {
 	int (*init_image)(struct pil_desc *pil, const u8 *metadata,
 			  size_t size);
 	int (*verify_blob)(struct pil_desc *pil, u32 phy_addr, size_t size);
+	int (*proxy_vote)(struct pil_desc *pil);
 	int (*auth_and_reset)(struct pil_desc *pil);
+	void (*proxy_unvote)(struct pil_desc *pil);
 	int (*shutdown)(struct pil_desc *pil);
 };
 
diff --git a/arch/arm/mach-msm/peripheral-reset-8960.c b/arch/arm/mach-msm/peripheral-reset-8960.c
deleted file mode 100644
index 7965193..0000000
--- a/arch/arm/mach-msm/peripheral-reset-8960.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * 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/err.h>
-#include <linux/io.h>
-#include <linux/elf.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-
-#include <mach/msm_iomap.h>
-#include <mach/scm.h>
-
-#include "peripheral-loader.h"
-#include "scm-pas.h"
-
-#define PPSS_RESET			(MSM_CLK_CTL_BASE + 0x2594)
-#define PPSS_PROC_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2588)
-#define PPSS_HCLK_CTL			(MSM_CLK_CTL_BASE + 0x2580)
-
-static int verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
-{
-	return 0;
-}
-
-static int init_image_dsps_untrusted(struct pil_desc *pil, const u8 *metadata,
-				     size_t size)
-{
-	/* Bring memory and bus interface out of reset */
-	writel_relaxed(0x2, PPSS_RESET);
-	writel_relaxed(0x10, PPSS_HCLK_CTL);
-	return 0;
-}
-
-static int reset_dsps_untrusted(struct pil_desc *pil)
-{
-	writel_relaxed(0x10, PPSS_PROC_CLK_CTL);
-	/* Bring DSPS out of reset */
-	writel_relaxed(0x0, PPSS_RESET);
-	return 0;
-}
-
-static int shutdown_dsps_untrusted(struct pil_desc *pil)
-{
-	writel_relaxed(0x3, PPSS_RESET);
-	writel_relaxed(0x0, PPSS_PROC_CLK_CTL);
-	return 0;
-}
-
-static int init_image_dsps_trusted(struct pil_desc *pil, const u8 *metadata,
-				   size_t size)
-{
-	return pas_init_image(PAS_DSPS, metadata, size);
-}
-
-static int reset_dsps_trusted(struct pil_desc *pil)
-{
-	return pas_auth_and_reset(PAS_DSPS);
-}
-
-static int shutdown_dsps_trusted(struct pil_desc *pil)
-{
-	return pas_shutdown(PAS_DSPS);
-}
-
-struct pil_reset_ops pil_dsps_ops = {
-	.init_image = init_image_dsps_untrusted,
-	.verify_blob = verify_blob,
-	.auth_and_reset = reset_dsps_untrusted,
-	.shutdown = shutdown_dsps_untrusted,
-};
-
-static struct platform_device pil_dsps = {
-	.name = "pil_dsps",
-};
-
-static struct pil_desc pil_dsps_desc = {
-	.name = "dsps",
-	.dev = &pil_dsps.dev,
-	.ops = &pil_dsps_ops,
-	.owner = THIS_MODULE,
-};
-
-static void __init use_secure_pil(void)
-{
-	if (pas_supported(PAS_DSPS) > 0) {
-		pil_dsps_ops.init_image = init_image_dsps_trusted;
-		pil_dsps_ops.auth_and_reset = reset_dsps_trusted;
-		pil_dsps_ops.shutdown = shutdown_dsps_trusted;
-	}
-}
-
-static int __init msm_peripheral_reset_init(void)
-{
-	/*
-	 * Don't initialize PIL on simulated targets, as some
-	 * subsystems may not be emulated on them.
-	 */
-	if (machine_is_msm8960_sim() || machine_is_msm8960_rumi3())
-		return 0;
-
-	use_secure_pil();
-
-	BUG_ON(platform_device_register(&pil_dsps));
-	BUG_ON(IS_ERR(msm_pil_register(&pil_dsps_desc)));
-
-	return 0;
-}
-module_init(msm_peripheral_reset_init);
diff --git a/arch/arm/mach-msm/peripheral-reset.c b/arch/arm/mach-msm/peripheral-reset.c
deleted file mode 100644
index 45617e3..0000000
--- a/arch/arm/mach-msm/peripheral-reset.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * 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/err.h>
-#include <linux/io.h>
-#include <linux/elf.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/timer.h>
-#include <linux/jiffies.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-
-#include <mach/scm.h>
-#include <mach/msm_iomap.h>
-
-#include "peripheral-loader.h"
-#include "scm-pas.h"
-
-#define PPSS_RESET			(MSM_CLK_CTL_BASE + 0x2594)
-#define PPSS_PROC_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2588)
-#define CLK_HALT_DFAB_STATE		(MSM_CLK_CTL_BASE + 0x2FC8)
-
-static int dsps_start;
-
-static int init_image_dsps_trusted(struct pil_desc *pil, const u8 *metadata,
-				   size_t size)
-{
-	return pas_init_image(PAS_DSPS, metadata, size);
-}
-
-static int init_image_dsps_untrusted(struct pil_desc *pil, const u8 *metadata,
-				     size_t size)
-{
-	struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
-	dsps_start = ehdr->e_entry;
-	/* Bring memory and bus interface out of reset */
-	__raw_writel(0x2, PPSS_RESET);
-	mb();
-	return 0;
-}
-
-static int verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
-{
-	return 0;
-}
-
-static int reset_dsps_untrusted(struct pil_desc *pil)
-{
-	__raw_writel(0x10, PPSS_PROC_CLK_CTL);
-	while (__raw_readl(CLK_HALT_DFAB_STATE) & BIT(18))
-		cpu_relax();
-
-	/* Bring DSPS out of reset */
-	__raw_writel(0x0, PPSS_RESET);
-	return 0;
-}
-
-static int reset_dsps_trusted(struct pil_desc *pil)
-{
-	return pas_auth_and_reset(PAS_DSPS);
-}
-
-static int shutdown_dsps_trusted(struct pil_desc *pil)
-{
-	return pas_shutdown(PAS_DSPS);
-}
-
-static int shutdown_dsps_untrusted(struct pil_desc *pil)
-{
-	__raw_writel(0x3, PPSS_RESET);
-	__raw_writel(0x0, PPSS_PROC_CLK_CTL);
-	return 0;
-}
-
-struct pil_reset_ops pil_dsps_ops = {
-	.init_image = init_image_dsps_untrusted,
-	.verify_blob = verify_blob,
-	.auth_and_reset = reset_dsps_untrusted,
-	.shutdown = shutdown_dsps_untrusted,
-};
-
-static struct platform_device pil_dsps = {
-	.name = "pil_dsps",
-};
-
-static struct pil_desc pil_dsps_desc = {
-	.name = "dsps",
-	.dev = &pil_dsps.dev,
-	.ops = &pil_dsps_ops,
-	.owner = THIS_MODULE,
-};
-
-static int __init msm_peripheral_reset_init(void)
-{
-	if (pas_supported(PAS_DSPS) > 0) {
-		pil_dsps_ops.init_image = init_image_dsps_trusted;
-		pil_dsps_ops.auth_and_reset = reset_dsps_trusted;
-		pil_dsps_ops.shutdown = shutdown_dsps_trusted;
-	}
-
-	if (machine_is_msm8x60_fluid())
-		pil_dsps_desc.name = "dsps_fluid";
-	BUG_ON(platform_device_register(&pil_dsps));
-	BUG_ON(IS_ERR(msm_pil_register(&pil_dsps_desc)));
-
-	return 0;
-}
-
-module_init(msm_peripheral_reset_init);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Validate and bring peripherals out of reset");
diff --git a/arch/arm/mach-msm/pil-dsps.c b/arch/arm/mach-msm/pil-dsps.c
new file mode 100644
index 0000000..81f5330
--- /dev/null
+++ b/arch/arm/mach-msm/pil-dsps.c
@@ -0,0 +1,146 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/elf.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <mach/msm_iomap.h>
+
+#include "peripheral-loader.h"
+#include "scm-pas.h"
+
+#define PPSS_RESET			(MSM_CLK_CTL_BASE + 0x2594)
+#define PPSS_RESET_PROC_RESET		0x2
+#define PPSS_RESET_RESET		0x1
+#define PPSS_PROC_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2588)
+#define CLK_BRANCH_ENA			0x10
+#define PPSS_HCLK_CTL			(MSM_CLK_CTL_BASE + 0x2580)
+#define CLK_HALT_DFAB_STATE		(MSM_CLK_CTL_BASE + 0x2FC8)
+
+static int init_image_dsps(struct pil_desc *pil, const u8 *metadata,
+				     size_t size)
+{
+	/* Bring memory and bus interface out of reset */
+	writel_relaxed(PPSS_RESET_PROC_RESET, PPSS_RESET);
+	writel_relaxed(CLK_BRANCH_ENA, PPSS_HCLK_CTL);
+	mb();
+	return 0;
+}
+
+static int reset_dsps(struct pil_desc *pil)
+{
+	writel_relaxed(CLK_BRANCH_ENA, PPSS_PROC_CLK_CTL);
+	while (readl_relaxed(CLK_HALT_DFAB_STATE) & BIT(18))
+		cpu_relax();
+	/* Bring DSPS out of reset */
+	writel_relaxed(0x0, PPSS_RESET);
+	return 0;
+}
+
+static int shutdown_dsps(struct pil_desc *pil)
+{
+	writel_relaxed(PPSS_RESET_PROC_RESET | PPSS_RESET_RESET, PPSS_RESET);
+	usleep_range(1000, 2000);
+	writel_relaxed(PPSS_RESET_PROC_RESET, PPSS_RESET);
+	writel_relaxed(0x0, PPSS_PROC_CLK_CTL);
+	return 0;
+}
+
+struct pil_reset_ops pil_dsps_ops = {
+	.init_image = init_image_dsps,
+	.auth_and_reset = reset_dsps,
+	.shutdown = shutdown_dsps,
+};
+
+static int init_image_dsps_trusted(struct pil_desc *pil, const u8 *metadata,
+				   size_t size)
+{
+	return pas_init_image(PAS_DSPS, metadata, size);
+}
+
+static int reset_dsps_trusted(struct pil_desc *pil)
+{
+	return pas_auth_and_reset(PAS_DSPS);
+}
+
+static int shutdown_dsps_trusted(struct pil_desc *pil)
+{
+	return pas_shutdown(PAS_DSPS);
+}
+
+struct pil_reset_ops pil_dsps_ops_trusted = {
+	.init_image = init_image_dsps_trusted,
+	.auth_and_reset = reset_dsps_trusted,
+	.shutdown = shutdown_dsps_trusted,
+};
+
+static int __devinit pil_dsps_driver_probe(struct platform_device *pdev)
+{
+	struct pil_desc *desc;
+	struct pil_device *pil;
+
+	desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+	desc->name = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->owner = THIS_MODULE;
+	if (pas_supported(PAS_DSPS) > 0) {
+		desc->ops = &pil_dsps_ops_trusted;
+		dev_info(&pdev->dev, "using secure boot\n");
+	} else {
+		desc->ops = &pil_dsps_ops;
+		dev_info(&pdev->dev, "using non-secure boot\n");
+	}
+	pil = msm_pil_register(desc);
+	if (IS_ERR(pil))
+		return PTR_ERR(pil);
+	platform_set_drvdata(pdev, pil);
+	return 0;
+}
+
+static int __devexit pil_dsps_driver_exit(struct platform_device *pdev)
+{
+	struct pil_device *pil = platform_get_drvdata(pdev);
+	msm_pil_unregister(pil);
+	return 0;
+}
+
+static struct platform_driver pil_dsps_driver = {
+	.probe = pil_dsps_driver_probe,
+	.remove = __devexit_p(pil_dsps_driver_exit),
+	.driver = {
+		.name = "pil_dsps",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pil_dsps_init(void)
+{
+	return platform_driver_register(&pil_dsps_driver);
+}
+module_init(pil_dsps_init);
+
+static void __exit pil_dsps_exit(void)
+{
+	platform_driver_unregister(&pil_dsps_driver);
+}
+module_exit(pil_dsps_exit);
+
+MODULE_DESCRIPTION("Support for booting sensors (DSPS) images");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index fa4f28c..f41a6e3 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -19,7 +19,6 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-#include <linux/workqueue.h>
 #include <linux/clk.h>
 #include <linux/smp.h>
 
@@ -58,13 +57,10 @@
 #define SLP_CLK_BRANCH_ENA	BIT(4)
 #define A5_RESET		BIT(0)
 
-#define PROXY_VOTE_TIMEOUT	10000
-
 struct gss_data {
 	void __iomem *base;
 	void __iomem *qgic2_base;
 	unsigned long start_addr;
-	struct delayed_work work;
 	struct clk *xo;
 	struct pil_device *pil;
 };
@@ -78,31 +74,25 @@
 	return 0;
 }
 
-static int make_gss_proxy_votes(struct device *dev)
+static int make_gss_proxy_votes(struct pil_desc *pil)
 {
 	int ret;
-	struct gss_data *drv = dev_get_drvdata(dev);
+	struct gss_data *drv = dev_get_drvdata(pil->dev);
 
 	ret = clk_prepare_enable(drv->xo);
 	if (ret) {
-		dev_err(dev, "Failed to enable XO\n");
+		dev_err(pil->dev, "Failed to enable XO\n");
 		return ret;
 	}
-	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
 	return 0;
 }
 
-static void remove_gss_proxy_votes(struct work_struct *work)
+static void remove_gss_proxy_votes(struct pil_desc *pil)
 {
-	struct gss_data *drv = container_of(work, struct gss_data, work.work);
+	struct gss_data *drv = dev_get_drvdata(pil->dev);
 	clk_disable_unprepare(drv->xo);
 }
 
-static void remove_gss_proxy_votes_now(struct gss_data *drv)
-{
-	flush_delayed_work(&drv->work);
-}
-
 static void gss_init(struct gss_data *drv)
 {
 	void __iomem *base = drv->base;
@@ -200,7 +190,6 @@
 	mb();
 
 	clk_disable_unprepare(drv->xo);
-	remove_gss_proxy_votes_now(drv);
 
 	return 0;
 }
@@ -212,15 +201,10 @@
 	unsigned long start_addr = drv->start_addr;
 	int ret;
 
-	ret = make_gss_proxy_votes(pil->dev);
-	if (ret)
-		return ret;
-
 	/* Unhalt bus port. */
 	ret = msm_bus_axi_portunhalt(MSM_BUS_MASTER_GSS_NAV);
 	if (ret) {
 		dev_err(pil->dev, "Failed to unhalt bus port\n");
-		remove_gss_proxy_votes_now(drv);
 		return ret;
 	}
 
@@ -262,6 +246,8 @@
 	.init_image = pil_gss_init_image,
 	.auth_and_reset = pil_gss_reset,
 	.shutdown = pil_gss_shutdown,
+	.proxy_vote = make_gss_proxy_votes,
+	.proxy_unvote = remove_gss_proxy_votes,
 };
 
 static int pil_gss_init_image_trusted(struct pil_desc *pil,
@@ -288,24 +274,18 @@
 	msm_bus_axi_porthalt(MSM_BUS_MASTER_GSS_NAV);
 	ret = pas_shutdown(PAS_GSS);
 	clk_disable_unprepare(drv->xo);
-	remove_gss_proxy_votes_now(drv);
 
 	return ret;
 }
 
 static int pil_gss_reset_trusted(struct pil_desc *pil)
 {
-	struct gss_data *drv = dev_get_drvdata(pil->dev);
 	int err;
 
-	err = make_gss_proxy_votes(pil->dev);
-	if (err)
-		goto out;
-
 	err = msm_bus_axi_portunhalt(MSM_BUS_MASTER_GSS_NAV);
 	if (err) {
 		dev_err(pil->dev, "Failed to unhalt bus port\n");
-		goto remove_votes;
+		goto out;
 	}
 
 	err =  pas_auth_and_reset(PAS_GSS);
@@ -316,8 +296,6 @@
 
 halt_port:
 	msm_bus_axi_porthalt(MSM_BUS_MASTER_GSS_NAV);
-remove_votes:
-	remove_gss_proxy_votes_now(drv);
 out:
 	return err;
 }
@@ -326,6 +304,8 @@
 	.init_image = pil_gss_init_image_trusted,
 	.auth_and_reset = pil_gss_reset_trusted,
 	.shutdown = pil_gss_shutdown_trusted,
+	.proxy_vote = make_gss_proxy_votes,
+	.proxy_unvote = remove_gss_proxy_votes,
 };
 
 static int __devinit pil_gss_probe(struct platform_device *pdev)
@@ -367,6 +347,7 @@
 	desc->name = "gss";
 	desc->dev = &pdev->dev;
 	desc->owner = THIS_MODULE;
+	desc->proxy_timeout = 10000;
 
 	if (pas_supported(PAS_GSS) > 0) {
 		desc->ops = &pil_gss_ops_trusted;
@@ -376,11 +357,8 @@
 		dev_info(&pdev->dev, "using non-secure boot\n");
 	}
 
-	INIT_DELAYED_WORK(&drv->work, remove_gss_proxy_votes);
-
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil)) {
-		flush_delayed_work_sync(&drv->work);
 		clk_put(drv->xo);
 		return PTR_ERR(drv->pil);
 	}
@@ -391,7 +369,6 @@
 {
 	struct gss_data *drv = platform_get_drvdata(pdev);
 	msm_pil_unregister(drv->pil);
-	flush_delayed_work_sync(&drv->work);
 	clk_put(drv->xo);
 	return 0;
 }
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 80e0ac9..998e606 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -18,7 +18,6 @@
 #include <linux/elf.h>
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/workqueue.h>
 #include <linux/clk.h>
 
 #include <mach/msm_iomap.h>
@@ -48,42 +47,32 @@
 #define PLL8_STATUS			(MSM_CLK_CTL_BASE + 0x3158)
 #define CLK_HALT_MSS_SMPSS_MISC_STATE	(MSM_CLK_CTL_BASE + 0x2FDC)
 
-#define PROXY_VOTE_TIMEOUT		10000
-
 struct modem_data {
 	void __iomem *base;
 	unsigned long start_addr;
 	struct pil_device *pil;
 	struct clk *xo;
-	struct delayed_work work;
 };
 
-static int make_modem_proxy_votes(struct device *dev)
+static int make_modem_proxy_votes(struct pil_desc *pil)
 {
 	int ret;
-	struct modem_data *drv = dev_get_drvdata(dev);
+	struct modem_data *drv = dev_get_drvdata(pil->dev);
 
 	ret = clk_prepare_enable(drv->xo);
 	if (ret) {
-		dev_err(dev, "Failed to enable XO\n");
+		dev_err(pil->dev, "Failed to enable XO\n");
 		return ret;
 	}
-	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
 	return 0;
 }
 
-static void remove_modem_proxy_votes(struct work_struct *work)
+static void remove_modem_proxy_votes(struct pil_desc *pil)
 {
-	struct modem_data *drv;
-	drv = container_of(work, struct modem_data, work.work);
+	struct modem_data *drv = dev_get_drvdata(pil->dev);
 	clk_disable_unprepare(drv->xo);
 }
 
-static void remove_modem_proxy_votes_now(struct modem_data *drv)
-{
-	flush_delayed_work(&drv->work);
-}
-
 static int modem_init_image(struct pil_desc *pil, const u8 *metadata,
 		size_t size)
 {
@@ -96,13 +85,8 @@
 static int modem_reset(struct pil_desc *pil)
 {
 	u32 reg;
-	int ret;
 	const struct modem_data *drv = dev_get_drvdata(pil->dev);
 
-	ret = make_modem_proxy_votes(pil->dev);
-	if (ret)
-		return ret;
-
 	/* Put modem AHB0,1,2 clocks into reset */
 	writel_relaxed(BIT(0) | BIT(1), MAHB0_SFAB_PORT_RESET);
 	writel_relaxed(BIT(7), MAHB1_CLK_CTL);
@@ -180,7 +164,6 @@
 static int modem_shutdown(struct pil_desc *pil)
 {
 	u32 reg;
-	struct modem_data *drv = dev_get_drvdata(pil->dev);
 
 	/* Put modem into reset */
 	writel_relaxed(0x1, MARM_RESET);
@@ -214,8 +197,6 @@
 	/* Clear modem's votes for PLLs */
 	writel_relaxed(0x0, PLL_ENA_MARM);
 
-	remove_modem_proxy_votes_now(drv);
-
 	return 0;
 }
 
@@ -223,6 +204,8 @@
 	.init_image = modem_init_image,
 	.auth_and_reset = modem_reset,
 	.shutdown = modem_shutdown,
+	.proxy_vote = make_modem_proxy_votes,
+	.proxy_unvote = remove_modem_proxy_votes,
 };
 
 static int modem_init_image_trusted(struct pil_desc *pil, const u8 *metadata,
@@ -233,37 +216,20 @@
 
 static int modem_reset_trusted(struct pil_desc *pil)
 {
-	int ret;
-	struct modem_data *drv = dev_get_drvdata(pil->dev);
-
-	ret = make_modem_proxy_votes(pil->dev);
-	if (ret)
-		return ret;
-
-	ret = pas_auth_and_reset(PAS_MODEM);
-	if (ret)
-		remove_modem_proxy_votes_now(drv);
-
-	return ret;
+	return pas_auth_and_reset(PAS_MODEM);
 }
 
 static int modem_shutdown_trusted(struct pil_desc *pil)
 {
-	int ret;
-	struct modem_data *drv = dev_get_drvdata(pil->dev);
-
-	ret = pas_shutdown(PAS_MODEM);
-	if (ret)
-		return ret;
-
-	remove_modem_proxy_votes_now(drv);
-	return 0;
+	return pas_shutdown(PAS_MODEM);
 }
 
 static struct pil_reset_ops pil_modem_ops_trusted = {
 	.init_image = modem_init_image_trusted,
 	.auth_and_reset = modem_reset_trusted,
 	.shutdown = modem_shutdown_trusted,
+	.proxy_vote = make_modem_proxy_votes,
+	.proxy_unvote = remove_modem_proxy_votes,
 };
 
 static int __devinit pil_modem_driver_probe(struct platform_device *pdev)
@@ -297,6 +263,7 @@
 	desc->depends_on = "q6";
 	desc->dev = &pdev->dev;
 	desc->owner = THIS_MODULE;
+	desc->proxy_timeout = 10000;
 
 	if (pas_supported(PAS_MODEM) > 0) {
 		desc->ops = &pil_modem_ops_trusted;
@@ -305,11 +272,8 @@
 		desc->ops = &pil_modem_ops;
 		dev_info(&pdev->dev, "using non-secure boot\n");
 	}
-	INIT_DELAYED_WORK(&drv->work, remove_modem_proxy_votes);
-
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil)) {
-		flush_delayed_work_sync(&drv->work);
 		clk_put(drv->xo);
 		return PTR_ERR(drv->pil);
 	}
@@ -320,7 +284,6 @@
 {
 	struct modem_data *drv = platform_get_drvdata(pdev);
 	msm_pil_unregister(drv->pil);
-	flush_delayed_work_sync(&drv->work);
 	clk_put(drv->xo);
 	return 0;
 }
diff --git a/arch/arm/mach-msm/pil-q6v3.c b/arch/arm/mach-msm/pil-q6v3.c
index 6c00ae7..235d881 100644
--- a/arch/arm/mach-msm/pil-q6v3.c
+++ b/arch/arm/mach-msm/pil-q6v3.c
@@ -19,7 +19,6 @@
 #include <linux/elf.h>
 #include <linux/err.h>
 #include <linux/clk.h>
-#include <linux/workqueue.h>
 
 #include <mach/msm_iomap.h>
 
@@ -61,14 +60,11 @@
 #define Q6_STRAP_TCM_BASE	(0x28C << 15)
 #define Q6_STRAP_TCM_CONFIG	0x28B
 
-#define PROXY_VOTE_TIMEOUT	10000
-
 struct q6v3_data {
 	void __iomem *base;
 	unsigned long start_addr;
 	struct pil_device *pil;
 	struct clk *pll;
-	struct delayed_work work;
 };
 
 static int pil_q6v3_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -80,41 +76,30 @@
 	return 0;
 }
 
-static void q6v3_remove_proxy_votes(struct work_struct *work)
+static void pil_q6v3_remove_proxy_votes(struct pil_desc *pil)
 {
-	struct q6v3_data *drv = container_of(work, struct q6v3_data, work.work);
+	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
 	clk_disable_unprepare(drv->pll);
 }
 
-static int q6v3_make_proxy_votes(struct device *dev)
+static int pil_q6v3_make_proxy_votes(struct pil_desc *pil)
 {
 	int ret;
-	struct q6v3_data *drv = dev_get_drvdata(dev);
+	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
 
 	ret = clk_prepare_enable(drv->pll);
 	if (ret) {
-		dev_err(dev, "Failed to enable PLL\n");
+		dev_err(pil->dev, "Failed to enable PLL\n");
 		return ret;
 	}
-	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
 	return 0;
 }
 
-static void q6v3_remove_proxy_votes_now(struct q6v3_data *drv)
-{
-	flush_delayed_work(&drv->work);
-}
-
 static int pil_q6v3_reset(struct pil_desc *pil)
 {
 	u32 reg;
-	int ret;
 	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
 
-	ret = q6v3_make_proxy_votes(pil->dev);
-	if (ret)
-		return ret;
-
 	/* Put Q6 into reset */
 	reg = readl_relaxed(LCC_Q6_FUNC);
 	reg |= Q6SS_SS_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES | STOP_CORE |
@@ -159,7 +144,6 @@
 static int pil_q6v3_shutdown(struct pil_desc *pil)
 {
 	u32 reg;
-	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
 
 	/* Put Q6 into reset */
 	reg = readl_relaxed(LCC_Q6_FUNC);
@@ -179,8 +163,6 @@
 	reg |= CLAMP_IO;
 	writel_relaxed(reg, LCC_Q6_FUNC);
 
-	q6v3_remove_proxy_votes_now(drv);
-
 	return 0;
 }
 
@@ -188,6 +170,8 @@
 	.init_image = pil_q6v3_init_image,
 	.auth_and_reset = pil_q6v3_reset,
 	.shutdown = pil_q6v3_shutdown,
+	.proxy_vote = pil_q6v3_make_proxy_votes,
+	.proxy_unvote = pil_q6v3_remove_proxy_votes,
 };
 
 static int pil_q6v3_init_image_trusted(struct pil_desc *pil,
@@ -198,31 +182,20 @@
 
 static int pil_q6v3_reset_trusted(struct pil_desc *pil)
 {
-	int ret;
-	ret = q6v3_make_proxy_votes(pil->dev);
-	if (ret)
-		return ret;
 	return pas_auth_and_reset(PAS_Q6);
 }
 
 static int pil_q6v3_shutdown_trusted(struct pil_desc *pil)
 {
-	int ret;
-	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
-
-	ret = pas_shutdown(PAS_Q6);
-	if (ret)
-		return ret;
-
-	q6v3_remove_proxy_votes_now(drv);
-
-	return 0;
+	return pas_shutdown(PAS_Q6);
 }
 
 static struct pil_reset_ops pil_q6v3_ops_trusted = {
 	.init_image = pil_q6v3_init_image_trusted,
 	.auth_and_reset = pil_q6v3_reset_trusted,
 	.shutdown = pil_q6v3_shutdown_trusted,
+	.proxy_vote = pil_q6v3_make_proxy_votes,
+	.proxy_unvote = pil_q6v3_remove_proxy_votes,
 };
 
 static int __devinit pil_q6v3_driver_probe(struct platform_device *pdev)
@@ -255,6 +228,7 @@
 	desc->name = "q6";
 	desc->dev = &pdev->dev;
 	desc->owner = THIS_MODULE;
+	desc->proxy_timeout = 10000;
 
 	if (pas_supported(PAS_Q6) > 0) {
 		desc->ops = &pil_q6v3_ops_trusted;
@@ -264,11 +238,8 @@
 		dev_info(&pdev->dev, "using non-secure boot\n");
 	}
 
-	INIT_DELAYED_WORK(&drv->work, q6v3_remove_proxy_votes);
-
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil)) {
-		flush_delayed_work_sync(&drv->work);
 		return PTR_ERR(drv->pil);
 	}
 	return 0;
@@ -278,7 +249,6 @@
 {
 	struct q6v3_data *drv = platform_get_drvdata(pdev);
 	msm_pil_unregister(drv->pil);
-	flush_delayed_work_sync(&drv->work);
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index b689846..b6ea03b 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -19,7 +19,6 @@
 #include <linux/elf.h>
 #include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/workqueue.h>
 #include <linux/clk.h>
 
 #include <mach/msm_bus.h>
@@ -29,8 +28,6 @@
 #include "pil-q6v4.h"
 #include "scm-pas.h"
 
-#define PROXY_VOTE_TIMEOUT	10000
-
 #define QDSP6SS_RST_EVB		0x0
 #define QDSP6SS_RESET		0x04
 #define QDSP6SS_STRAP_TCM	0x1C
@@ -70,7 +67,6 @@
 	struct regulator *pll_supply;
 	bool vreg_enabled;
 	struct clk *xo;
-	struct delayed_work work;
 	struct pil_device *pil;
 };
 
@@ -83,24 +79,23 @@
 	return 0;
 }
 
-static int pil_q6v4_make_proxy_votes(struct device *dev)
+static int pil_q6v4_make_proxy_votes(struct pil_desc *pil)
 {
-	struct q6v4_data *drv = dev_get_drvdata(dev);
+	const struct q6v4_data *drv = dev_get_drvdata(pil->dev);
 	int ret;
 
 	ret = clk_prepare_enable(drv->xo);
 	if (ret) {
-		dev_err(dev, "Failed to enable XO\n");
+		dev_err(pil->dev, "Failed to enable XO\n");
 		goto err;
 	}
 	if (drv->pll_supply) {
 		ret = regulator_enable(drv->pll_supply);
 		if (ret) {
-			dev_err(dev, "Failed to enable pll supply\n");
+			dev_err(pil->dev, "Failed to enable pll supply\n");
 			goto err_regulator;
 		}
 	}
-	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
 	return 0;
 err_regulator:
 	clk_disable_unprepare(drv->xo);
@@ -108,20 +103,14 @@
 	return ret;
 }
 
-static void pil_q6v4_remove_proxy_votes(struct work_struct *work)
+static void pil_q6v4_remove_proxy_votes(struct pil_desc *pil)
 {
-	struct q6v4_data *drv = container_of(work, struct q6v4_data, work.work);
+	const struct q6v4_data *drv = dev_get_drvdata(pil->dev);
 	if (drv->pll_supply)
 		regulator_disable(drv->pll_supply);
 	clk_disable_unprepare(drv->xo);
 }
 
-static void pil_q6v4_remove_proxy_votes_now(struct device *dev)
-{
-	struct q6v4_data *drv = dev_get_drvdata(dev);
-	flush_delayed_work(&drv->work);
-}
-
 static int pil_q6v4_power_up(struct device *dev)
 {
 	int err;
@@ -192,14 +181,10 @@
 
 static int pil_q6v4_reset(struct pil_desc *pil)
 {
-	u32 reg, err = 0;
+	u32 reg, err;
 	const struct q6v4_data *drv = dev_get_drvdata(pil->dev);
 	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
 
-	err = pil_q6v4_make_proxy_votes(pil->dev);
-	if (err)
-		return err;
-
 	err = pil_q6v4_power_up(pil->dev);
 	if (err)
 		return err;
@@ -295,8 +280,6 @@
 		drv->vreg_enabled = false;
 	}
 
-	pil_q6v4_remove_proxy_votes_now(pil->dev);
-
 	return 0;
 }
 
@@ -304,6 +287,8 @@
 	.init_image = pil_q6v4_init_image,
 	.auth_and_reset = pil_q6v4_reset,
 	.shutdown = pil_q6v4_shutdown,
+	.proxy_vote = pil_q6v4_make_proxy_votes,
+	.proxy_unvote = pil_q6v4_remove_proxy_votes,
 };
 
 static int pil_q6v4_init_image_trusted(struct pil_desc *pil,
@@ -318,10 +303,6 @@
 	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
 	int err;
 
-	err = pil_q6v4_make_proxy_votes(pil->dev);
-	if (err)
-		return err;
-
 	err = pil_q6v4_power_up(pil->dev);
 	if (err)
 		return err;
@@ -351,8 +332,6 @@
 		drv->vreg_enabled = false;
 	}
 
-	pil_q6v4_remove_proxy_votes_now(pil->dev);
-
 	return ret;
 }
 
@@ -360,6 +339,8 @@
 	.init_image = pil_q6v4_init_image_trusted,
 	.auth_and_reset = pil_q6v4_reset_trusted,
 	.shutdown = pil_q6v4_shutdown_trusted,
+	.proxy_vote = pil_q6v4_make_proxy_votes,
+	.proxy_unvote = pil_q6v4_remove_proxy_votes,
 };
 
 static int __devinit pil_q6v4_driver_probe(struct platform_device *pdev)
@@ -395,7 +376,7 @@
 	if (!desc)
 		return -ENOMEM;
 
-	drv->pll_supply = regulator_get(&pdev->dev, "pll_vdd");
+	drv->pll_supply = devm_regulator_get(&pdev->dev, "pll_vdd");
 	if (IS_ERR(drv->pll_supply)) {
 		drv->pll_supply = NULL;
 	} else {
@@ -416,6 +397,7 @@
 	desc->depends_on = pdata->depends;
 	desc->dev = &pdev->dev;
 	desc->owner = THIS_MODULE;
+	desc->proxy_timeout = 10000;
 
 	if (pas_supported(pdata->pas_id) > 0) {
 		desc->ops = &pil_q6v4_ops_trusted;
@@ -425,7 +407,7 @@
 		dev_info(&pdev->dev, "using non-secure boot\n");
 	}
 
-	drv->vreg = regulator_get(&pdev->dev, "core_vdd");
+	drv->vreg = devm_regulator_get(&pdev->dev, "core_vdd");
 	if (IS_ERR(drv->vreg)) {
 		ret = PTR_ERR(drv->vreg);
 		goto err;
@@ -434,9 +416,8 @@
 	drv->xo = clk_get(&pdev->dev, "xo");
 	if (IS_ERR(drv->xo)) {
 		ret = PTR_ERR(drv->xo);
-		goto err_xo;
+		goto err;
 	}
-	INIT_DELAYED_WORK(&drv->work, pil_q6v4_remove_proxy_votes);
 
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil)) {
@@ -445,22 +426,15 @@
 	}
 	return 0;
 err_pil:
-	flush_delayed_work_sync(&drv->work);
 	clk_put(drv->xo);
-err_xo:
-	regulator_put(drv->vreg);
 err:
-	regulator_put(drv->pll_supply);
 	return ret;
 }
 
 static int __devexit pil_q6v4_driver_exit(struct platform_device *pdev)
 {
 	struct q6v4_data *drv = platform_get_drvdata(pdev);
-	flush_delayed_work_sync(&drv->work);
 	clk_put(drv->xo);
-	regulator_put(drv->vreg);
-	regulator_put(drv->pll_supply);
 	msm_pil_unregister(drv->pil);
 	return 0;
 }
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 24a78f0..92339e9 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -19,17 +19,13 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
-#include <linux/workqueue.h>
 #include <linux/clk.h>
-#include <linux/wakelock.h>
 
 #include <mach/msm_iomap.h>
 
 #include "peripheral-loader.h"
 #include "scm-pas.h"
 
-#define PROXY_VOTE_TIMEOUT		10000
-
 #define RIVA_PMU_A2XB_CFG		0xB8
 #define RIVA_PMU_A2XB_CFG_EN		BIT(0)
 
@@ -85,31 +81,35 @@
 	unsigned long start_addr;
 	struct clk *xo;
 	bool use_cxo;
-	struct delayed_work work;
 	struct regulator *pll_supply;
 	struct pil_device *pil;
-	struct wake_lock wlock;
 };
 
-static int pil_riva_make_proxy_votes(struct device *dev)
+static bool cxo_is_needed(struct riva_data *drv)
 {
-	struct riva_data *drv = dev_get_drvdata(dev);
+	u32 reg = readl_relaxed(drv->base + RIVA_PMU_CFG);
+	return (reg & RIVA_PMU_CFG_IRIS_XO_MODE)
+		!= RIVA_PMU_CFG_IRIS_XO_MODE_48;
+}
+
+static int pil_riva_make_proxy_vote(struct pil_desc *pil)
+{
+	struct riva_data *drv = dev_get_drvdata(pil->dev);
 	int ret;
 
-	wake_lock(&drv->wlock);
+	drv->use_cxo = cxo_is_needed(drv);
 	ret = regulator_enable(drv->pll_supply);
 	if (ret) {
-		dev_err(dev, "failed to enable pll supply\n");
+		dev_err(pil->dev, "failed to enable pll supply\n");
 		goto err;
 	}
 	if (drv->use_cxo) {
 		ret = clk_prepare_enable(drv->xo);
 		if (ret) {
-			dev_err(dev, "failed to enable xo\n");
+			dev_err(pil->dev, "failed to enable xo\n");
 			goto err_clk;
 		}
 	}
-	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
 	return 0;
 err_clk:
 	regulator_disable(drv->pll_supply);
@@ -117,19 +117,12 @@
 	return ret;
 }
 
-static void pil_riva_remove_proxy_votes(struct work_struct *work)
+static void pil_riva_remove_proxy_vote(struct pil_desc *pil)
 {
-	struct riva_data *drv = container_of(work, struct riva_data, work.work);
+	struct riva_data *drv = dev_get_drvdata(pil->dev);
 	regulator_disable(drv->pll_supply);
 	if (drv->use_cxo)
 		clk_disable_unprepare(drv->xo);
-	wake_unlock(&drv->wlock);
-}
-
-static void pil_riva_remove_proxy_votes_now(struct device *dev)
-{
-	struct riva_data *drv = dev_get_drvdata(dev);
-	flush_delayed_work(&drv->work);
 }
 
 static int pil_riva_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -141,13 +134,6 @@
 	return 0;
 }
 
-static bool cxo_is_needed(struct riva_data *drv)
-{
-	u32 reg = readl_relaxed(drv->base + RIVA_PMU_CFG);
-	return (reg & RIVA_PMU_CFG_IRIS_XO_MODE)
-		!= RIVA_PMU_CFG_IRIS_XO_MODE_48;
-}
-
 static int pil_riva_reset(struct pil_desc *pil)
 {
 	u32 reg, sel;
@@ -164,16 +150,6 @@
 	reg |= RIVA_PMU_A2XB_CFG_EN;
 	writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
 
-	drv->use_cxo = cxo_is_needed(drv);
-	ret = pil_riva_make_proxy_votes(pil->dev);
-	if (ret) {
-		reg &= ~RIVA_PMU_A2XB_CFG_EN;
-		writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
-		mb();
-		clk_disable_unprepare(drv->xo);
-		return ret;
-	}
-
 	/* Program PLL 13 to 960 MHz */
 	reg = readl_relaxed(RIVA_PLL_MODE);
 	reg &= ~(PLL_MODE_BYPASSNL | PLL_MODE_OUTCTRL | PLL_MODE_RESET_N);
@@ -287,7 +263,6 @@
 	mb();
 
 	clk_disable_unprepare(drv->xo);
-	pil_riva_remove_proxy_votes_now(pil->dev);
 
 	return 0;
 }
@@ -296,6 +271,8 @@
 	.init_image = pil_riva_init_image,
 	.auth_and_reset = pil_riva_reset,
 	.shutdown = pil_riva_shutdown,
+	.proxy_vote = pil_riva_make_proxy_vote,
+	.proxy_unvote = pil_riva_remove_proxy_vote,
 };
 
 static int pil_riva_init_image_trusted(struct pil_desc *pil,
@@ -313,9 +290,7 @@
 	if (ret)
 		return ret;
 	/* Proxy-vote for resources RIVA needs */
-	ret = pil_riva_make_proxy_votes(pil->dev);
-	if (!ret)
-		ret = pas_auth_and_reset(PAS_RIVA);
+	ret = pas_auth_and_reset(PAS_RIVA);
 	clk_disable_unprepare(drv->xo);
 	return ret;
 }
@@ -329,7 +304,6 @@
 	if (ret)
 		return ret;
 	ret = pas_shutdown(PAS_RIVA);
-	pil_riva_remove_proxy_votes_now(pil->dev);
 	clk_disable_unprepare(drv->xo);
 
 	return ret;
@@ -339,6 +313,8 @@
 	.init_image = pil_riva_init_image_trusted,
 	.auth_and_reset = pil_riva_reset_trusted,
 	.shutdown = pil_riva_shutdown_trusted,
+	.proxy_vote = pil_riva_make_proxy_vote,
+	.proxy_unvote = pil_riva_remove_proxy_vote,
 };
 
 static int __devinit pil_riva_probe(struct platform_device *pdev)
@@ -365,7 +341,7 @@
 	if (!desc)
 		return -ENOMEM;
 
-	drv->pll_supply = regulator_get(&pdev->dev, "pll_vdd");
+	drv->pll_supply = devm_regulator_get(&pdev->dev, "pll_vdd");
 	if (IS_ERR(drv->pll_supply)) {
 		dev_err(&pdev->dev, "failed to get pll supply\n");
 		return PTR_ERR(drv->pll_supply);
@@ -389,6 +365,7 @@
 	desc->name = "wcnss";
 	desc->dev = &pdev->dev;
 	desc->owner = THIS_MODULE;
+	desc->proxy_timeout = 10000;
 
 	if (pas_supported(PAS_RIVA) > 0) {
 		desc->ops = &pil_riva_ops_trusted;
@@ -403,8 +380,6 @@
 		ret = PTR_ERR(drv->xo);
 		goto err;
 	}
-	wake_lock_init(&drv->wlock, WAKE_LOCK_SUSPEND, "riva-wlock");
-	INIT_DELAYED_WORK(&drv->work, pil_riva_remove_proxy_votes);
 
 	drv->pil = msm_pil_register(desc);
 	if (IS_ERR(drv->pil)) {
@@ -413,11 +388,8 @@
 	}
 	return 0;
 err_register:
-	flush_delayed_work_sync(&drv->work);
-	wake_lock_destroy(&drv->wlock);
 	clk_put(drv->xo);
 err:
-	regulator_put(drv->pll_supply);
 	return ret;
 }
 
@@ -425,10 +397,7 @@
 {
 	struct riva_data *drv = platform_get_drvdata(pdev);
 	msm_pil_unregister(drv->pil);
-	flush_delayed_work_sync(&drv->work);
-	wake_lock_destroy(&drv->wlock);
 	clk_put(drv->xo);
-	regulator_put(drv->pll_supply);
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index f65b8ad..80e5a55 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -102,6 +102,7 @@
 {
 	int ret = 0;
 	unsigned long entry;
+	void __iomem *warm_boot_ptr;
 
 	switch (pdata->mode) {
 	case MSM_PM_BOOT_CONFIG_TZ:
@@ -124,16 +125,17 @@
 			= msm_pm_config_rst_vector_after_pc;
 		break;
 	case MSM_PM_BOOT_CONFIG_REMAP_BOOT_ADDR:
-		/*
-		 * Set the boot remap address and enable remapping of
-		 * reset vector
-		 */
-		if (!pdata->p_addr || !pdata->v_addr)
-			return -ENODEV;
-
-		ret = msm_pm_boot_reset_vector_init(__va(pdata->p_addr));
-
 		if (!cpu_is_msm8625()) {
+			/*
+			 * Set the boot remap address and enable remapping of
+			 * reset vector
+			 */
+			if (!pdata->p_addr || !pdata->v_addr)
+				return -ENODEV;
+
+			ret = msm_pm_boot_reset_vector_init(
+							__va(pdata->p_addr));
+
 			__raw_writel((pdata->p_addr | BOOT_REMAP_ENABLE),
 					pdata->v_addr);
 
@@ -142,6 +144,10 @@
 			msm_pm_boot_after_pc
 				= msm_pm_config_rst_vector_after_pc;
 		} else {
+			warm_boot_ptr = ioremap_nocache(
+						MSM8625_WARM_BOOT_PHYS, SZ_64);
+			ret = msm_pm_boot_reset_vector_init(warm_boot_ptr);
+
 			entry = virt_to_phys(msm_pm_boot_entry);
 
 			/* Below sequence is a work around for cores
@@ -159,8 +165,8 @@
 			/* Here upper 16bits[16:31] used by CORE1
 			 * lower 16bits[0:15] used by CORE0
 			 */
-			entry = (pdata->p_addr) |
-					((pdata->p_addr & 0xFFFF0000) >> 16);
+			entry = (MSM8625_WARM_BOOT_PHYS |
+				((MSM8625_WARM_BOOT_PHYS & 0xFFFF0000) >> 16));
 
 			/* write 'entry' to boot remapper register */
 			__raw_writel(entry, (pdata->v_addr +
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index c66c809..7903eab 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -28,6 +28,7 @@
 #include <linux/reboot.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/tick.h>
 #include <linux/memory.h>
 #ifdef CONFIG_HAS_WAKELOCK
 #include <linux/wakelock.h>
@@ -49,6 +50,7 @@
 #include <mach/msm_migrate_pages.h>
 #endif
 #include <mach/socinfo.h>
+#include <asm/smp_scu.h>
 
 #include "smd_private.h"
 #include "smd_rpcrouter.h"
@@ -63,6 +65,7 @@
 #include "spm.h"
 #include "sirc.h"
 #include "pm-boot.h"
+#define MSM_CORE1_RESET		0xA8600590
 
 /******************************************************************************
  * Debug Definitions
@@ -478,10 +481,78 @@
 }
 
 /*
+ * Program the top csr from core0 context to put the
+ * core1 into GDFS, as core1 is not running yet.
+ */
+static void configure_top_csr(void)
+{
+	void __iomem *base_ptr;
+	unsigned int value = 0;
+
+	base_ptr = ioremap_nocache(MSM_CORE1_RESET, SZ_4);
+	if (!base_ptr)
+		return;
+
+	/* bring the core1 out of reset */
+	__raw_writel(0x3, base_ptr);
+	mb();
+	/*
+	 * override DBGNOPOWERDN and program the GDFS
+	 * count val
+	 */
+
+	 __raw_writel(0x00030002, (MSM_CFG_CTL_BASE + 0x38));
+	mb();
+
+	/* Initialize the SPM0 and SPM1 registers */
+	msm_spm_reinit();
+
+	/* enable TCSR for core1 */
+	value = __raw_readl((MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG));
+	value |= BIT(22);
+	__raw_writel(value,  MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG);
+	mb();
+
+	/* set reset bit for SPM1 */
+	value = __raw_readl((MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG));
+	value |= BIT(20);
+	__raw_writel(value,  MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG);
+	mb();
+
+	/* set CLK_OFF bit */
+	value = __raw_readl((MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG));
+	value |= BIT(18);
+	__raw_writel(value,  MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG);
+	mb();
+
+	/* set clamps bit */
+	value = __raw_readl((MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG));
+	value |= BIT(21);
+	__raw_writel(value,  MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG);
+	mb();
+
+	/* set power_up bit */
+	value = __raw_readl((MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG));
+	value |= BIT(19);
+	__raw_writel(value,  MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG);
+	mb();
+
+	/* Disable TSCR for core0 */
+	value = __raw_readl((MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG));
+	value &= ~BIT(22);
+	__raw_writel(value,  MSM_CFG_CTL_BASE + MPA5_CFG_CTL_REG);
+	mb();
+	__raw_writel(0x0, base_ptr);
+	mb();
+	iounmap(base_ptr);
+}
+
+/*
  * Clear hardware registers after Apps powers up.
  */
 static void msm_pm_config_hw_after_power_up(void)
 {
+
 	if (cpu_is_msm7x30() || cpu_is_msm8x55()) {
 		__raw_writel(0, APPS_SECOP);
 		mb();
@@ -493,6 +564,18 @@
 		mb();
 		__raw_writel(0, APPS_CLK_SLEEP_EN);
 		mb();
+
+		if (cpu_is_msm8625()) {
+			/*
+			 * enable the SCU while coming out of power
+			 * collapse.
+			 */
+			scu_enable(MSM_SCU_BASE);
+			/*
+			 * Program the top csr to put the core1 into GDFS.
+			 */
+			configure_top_csr();
+		}
 	}
 }
 
@@ -1359,7 +1442,7 @@
 	ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false);
 	WARN_ON(ret);
 
-	return 0;
+	return !collapsed;
 }
 
 /*
@@ -1415,17 +1498,15 @@
 	bool allow[MSM_PM_SLEEP_MODE_NR];
 	uint32_t sleep_limit = SLEEP_LIMIT_NONE;
 
-	int latency_qos;
 	int64_t timer_expiration;
-
-	int low_power;
+	int latency_qos;
 	int ret;
 	int i;
 	unsigned int cpu;
 
 #ifdef CONFIG_MSM_IDLE_STATS
 	int64_t t1;
-	static int64_t t2;
+	static DEFINE_PER_CPU(int64_t, t2);
 	int exit_stat;
  #endif
 
@@ -1435,15 +1516,14 @@
 	cpu = smp_processor_id();
 
 	latency_qos = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
-	timer_expiration = msm_timer_enter_idle();
+	/* get the next timer expiration */
+	timer_expiration = ktime_to_ns(tick_nohz_get_sleep_length());
 
 #ifdef CONFIG_MSM_IDLE_STATS
 	t1 = ktime_to_ns(ktime_get());
-	msm_pm_add_stat(MSM_PM_STAT_NOT_IDLE, t1 - t2);
+	msm_pm_add_stat(MSM_PM_STAT_NOT_IDLE, t1 - __get_cpu_var(t2));
 	msm_pm_add_stat(MSM_PM_STAT_REQUESTED_IDLE, timer_expiration);
-
 	exit_stat = MSM_PM_STAT_IDLE_SPIN;
-	low_power = 0;
 #endif
 
 	for (i = 0; i < ARRAY_SIZE(allow); i++)
@@ -1499,10 +1579,16 @@
 
 	if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] ||
 		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN]) {
+		/* Sync the timer with SCLK, it is needed only for modem
+		 * assissted pollapse case.
+		 */
+		int64_t next_timer_exp = msm_timer_enter_idle();
 		uint32_t sleep_delay;
+		bool low_power = false;
 
 		sleep_delay = (uint32_t) msm_pm_convert_and_cap_time(
-			timer_expiration, MSM_PM_SLEEP_TICK_LIMIT);
+			next_timer_exp, MSM_PM_SLEEP_TICK_LIMIT);
+
 		if (sleep_delay == 0) /* 0 would mean infinite time */
 			sleep_delay = 1;
 
@@ -1517,6 +1603,7 @@
 
 		ret = msm_pm_power_collapse(true, sleep_delay, sleep_limit);
 		low_power = (ret != -EBUSY && ret != -ETIMEDOUT);
+		msm_timer_exit_idle(low_power);
 
 #ifdef CONFIG_MSM_IDLE_STATS
 		if (ret)
@@ -1528,7 +1615,6 @@
 #endif
 	} else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
 		ret = msm_pm_power_collapse_standalone(true);
-		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = ret ?
 			MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE :
@@ -1539,30 +1625,25 @@
 		if (ret)
 			while (!msm_pm_irq_extns->irq_pending())
 				udelay(1);
-		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = ret ? MSM_PM_STAT_IDLE_SPIN : MSM_PM_STAT_IDLE_WFI;
 #endif
 	} else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
 		msm_pm_swfi(false);
-		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = MSM_PM_STAT_IDLE_WFI;
 #endif
 	} else {
 		while (!msm_pm_irq_extns->irq_pending())
 			udelay(1);
-		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
 		exit_stat = MSM_PM_STAT_IDLE_SPIN;
 #endif
 	}
 
-	msm_timer_exit_idle(low_power);
-
 #ifdef CONFIG_MSM_IDLE_STATS
-	t2 = ktime_to_ns(ktime_get());
-	msm_pm_add_stat(exit_stat, t2 - t1);
+	__get_cpu_var(t2) = ktime_to_ns(ktime_get());
+	msm_pm_add_stat(exit_stat, __get_cpu_var(t2) - t1);
 #endif
 }
 
@@ -1842,7 +1923,6 @@
 
 	BUG_ON(msm_pm_modes == NULL);
 
-	atomic_set(&msm_pm_init_done, 1);
 	suspend_set_ops(&msm_pm_ops);
 
 	msm_pm_mode_sysfs_add();
@@ -1898,6 +1978,9 @@
 		stats[MSM_PM_STAT_NOT_IDLE].first_bucket_time =
 			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
 	}
+
+	atomic_set(&msm_pm_init_done, 1);
+
 	d_entry = create_proc_entry("msm_pm_stats",
 			S_IRUGO | S_IWUSR | S_IWGRP, NULL);
 	if (d_entry) {
diff --git a/arch/arm/mach-msm/proccomm-regulator.c b/arch/arm/mach-msm/proccomm-regulator.c
index ba10d38..fff3a11 100644
--- a/arch/arm/mach-msm/proccomm-regulator.c
+++ b/arch/arm/mach-msm/proccomm-regulator.c
@@ -196,7 +196,7 @@
 static struct regulator_dev *__devinit create_proccomm_rdev(
 	struct proccomm_regulator_info *info, struct device *parent)
 {
-	char *name;
+	const char *name;
 	struct proccomm_regulator_drvdata *d;
 	struct regulator_dev *rdev;
 	int rc = 0;
@@ -247,7 +247,7 @@
 	d->negative	= info->negative;
 	d->rdesc.n_voltages = info->n_voltages;
 
-	rdev = regulator_register(&d->rdesc, parent, &info->init_data, d);
+	rdev = regulator_register(&d->rdesc, parent, &info->init_data, d, NULL);
 
 	if (IS_ERR(rdev)) {
 		rc = PTR_ERR(rdev);
diff --git a/arch/arm/mach-msm/qdsp5/audio_lpa.c b/arch/arm/mach-msm/qdsp5/audio_lpa.c
index dab53dc..9521e87 100644
--- a/arch/arm/mach-msm/qdsp5/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5/audio_lpa.c
@@ -73,7 +73,7 @@
 
 /* Size must be power of 2 */
 #define MAX_BUF 2
-#define BUFSZ (524288)
+#define BUFSZ (167210)
 
 #define AUDDEC_DEC_PCM 0
 
diff --git a/arch/arm/mach-msm/rpm-regulator.c b/arch/arm/mach-msm/rpm-regulator.c
index 719ea8a..c708df5 100644
--- a/arch/arm/mach-msm/rpm-regulator.c
+++ b/arch/arm/mach-msm/rpm-regulator.c
@@ -1330,7 +1330,7 @@
 	if (rc)
 		goto bail;
 
-	rdev = regulator_register(rdesc, dev, &(pdata->init_data), vreg);
+	rdev = regulator_register(rdesc, dev, &(pdata->init_data), vreg, NULL);
 	if (IS_ERR(rdev)) {
 		rc = PTR_ERR(rdev);
 		pr_err("regulator_register failed: %s, rc=%d\n",
diff --git a/arch/arm/mach-msm/saw-regulator.c b/arch/arm/mach-msm/saw-regulator.c
index b11b1fa..c747e5b 100644
--- a/arch/arm/mach-msm/saw-regulator.c
+++ b/arch/arm/mach-msm/saw-regulator.c
@@ -174,8 +174,8 @@
 	vreg->desc.owner = THIS_MODULE;
 	vreg->uV	 = MIN_CORE_VOLTAGE;
 
-	vreg->rdev = regulator_register(&vreg->desc, &pdev->dev, init_data,
-					vreg);
+	vreg->rdev = regulator_register(&vreg->desc, &pdev->dev,
+							init_data, vreg, NULL);
 	if (IS_ERR(vreg->rdev)) {
 		rc = PTR_ERR(vreg->rdev);
 		pr_err("regulator_register failed, rc=%d.\n", rc);
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index ae7bc32..ea8356c 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1032,7 +1032,7 @@
 		gpt->freq = 32765;
 		gpt_hz = 32765;
 		sclk_hz = 32765;
-		if (!machine_is_apq8064_rumi3()) {
+		if (!cpu_is_msm8930()) {
 			gpt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
 			dgt->flags |= MSM_CLOCK_FLAGS_UNSTABLE_COUNT;
 		}
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index bc5ffce..5c24578 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -484,6 +484,16 @@
 
 		/* Invalidate the cache */
 		l2x0_inv_all();
+		/*
+		 * TBD: make sure that l2xo_inv_all finished
+		 * before actually enabling the cache. Logically this
+		 * is not required as cache sync is atomic operation.
+		 * but on 8x25, observed the random crashes and they go
+		 * away if we add dmb or disable the L2.
+		 * keeping this as temporary workaround until root
+		 * cause is find out.
+		 */
+		dmb();
 	}
 
 	/* Enable the cache */
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 58f4720..338e8c2 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -36,6 +36,8 @@
 		return "arm/armv6";
 	case ARM_PERF_PMU_ID_V6MP:
 		return "arm/mpcore";
+	case ARM_PERF_PMU_ID_CA5:
+		return "arm/armv7";
 	case ARM_PERF_PMU_ID_CA8:
 		return "arm/armv7";
 	case ARM_PERF_PMU_ID_CA9:
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index cd32152..926bd69 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -164,7 +164,8 @@
 	unsigned char *buf_in_qdsp_1;
 	unsigned char *buf_in_qdsp_2;
 	unsigned char *buf_in_qdsp_cntl;
-	unsigned char *buf_in_wcnss;
+	unsigned char *buf_in_wcnss_1;
+	unsigned char *buf_in_wcnss_2;
 	unsigned char *buf_in_wcnss_cntl;
 	unsigned char *usb_buf_out;
 	unsigned char *apps_rsp_buf;
@@ -183,7 +184,8 @@
 	int in_busy_2;
 	int in_busy_qdsp_1;
 	int in_busy_qdsp_2;
-	int in_busy_wcnss;
+	int in_busy_wcnss_1;
+	int in_busy_wcnss_2;
 	int read_len_legacy;
 	unsigned char *hdlc_buf;
 	unsigned hdlc_count;
@@ -222,7 +224,8 @@
 	struct diag_request *write_ptr_svc;
 	struct diag_request *write_ptr_qdsp_1;
 	struct diag_request *write_ptr_qdsp_2;
-	struct diag_request *write_ptr_wcnss;
+	struct diag_request *write_ptr_wcnss_1;
+	struct diag_request *write_ptr_wcnss_2;
 	int logging_mode;
 	int mask_check;
 	int logging_process_id;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index d9f12ac..7e2333a 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -424,7 +424,8 @@
 			driver->in_busy_2 = 1;
 			driver->in_busy_qdsp_1 = 1;
 			driver->in_busy_qdsp_2 = 1;
-			driver->in_busy_wcnss = 1;
+			driver->in_busy_wcnss_1 = 1;
+			driver->in_busy_wcnss_2 = 1;
 #ifdef CONFIG_DIAG_SDIO_PIPE
 			driver->in_busy_sdio = 1;
 #endif
@@ -434,7 +435,8 @@
 			driver->in_busy_2 = 0;
 			driver->in_busy_qdsp_1 = 0;
 			driver->in_busy_qdsp_2 = 0;
-			driver->in_busy_wcnss = 0;
+			driver->in_busy_wcnss_1 = 0;
+			driver->in_busy_wcnss_2 = 0;
 			/* Poll SMD channels to check for data*/
 			if (driver->ch)
 				queue_work(driver->diag_wq,
@@ -465,9 +467,10 @@
 			diagfwd_disconnect();
 			driver->in_busy_1 = 0;
 			driver->in_busy_2 = 0;
+			driver->in_busy_qdsp_1 = 0;
 			driver->in_busy_qdsp_2 = 0;
-			driver->in_busy_qdsp_2 = 0;
-			driver->in_busy_wcnss = 0;
+			driver->in_busy_wcnss_1 = 0;
+			driver->in_busy_wcnss_2 = 0;
 			/* Poll SMD channels to check for data*/
 			if (driver->ch)
 				queue_work(driver->diag_wq,
@@ -607,16 +610,27 @@
 			driver->in_busy_qdsp_2 = 0;
 		}
 		/* copy wncss data */
-		if (driver->in_busy_wcnss == 1) {
+		if (driver->in_busy_wcnss_1 == 1) {
 			num_data++;
 			/*Copy the length of data being passed*/
 			COPY_USER_SPACE_OR_EXIT(buf+ret,
-				 (driver->write_ptr_wcnss->length), 4);
+				 (driver->write_ptr_wcnss_1->length), 4);
 			/*Copy the actual data being passed*/
 			COPY_USER_SPACE_OR_EXIT(buf+ret, *(driver->
-							buf_in_wcnss),
-					 driver->write_ptr_wcnss->length);
-			driver->in_busy_wcnss = 0;
+							buf_in_wcnss_1),
+					 driver->write_ptr_wcnss_1->length);
+			driver->in_busy_wcnss_1 = 0;
+		}
+		if (driver->in_busy_wcnss_2 == 1) {
+			num_data++;
+			/*Copy the length of data being passed*/
+			COPY_USER_SPACE_OR_EXIT(buf+ret,
+				 (driver->write_ptr_wcnss_2->length), 4);
+			/*Copy the actual data being passed*/
+			COPY_USER_SPACE_OR_EXIT(buf+ret, *(driver->
+							buf_in_wcnss_2),
+					 driver->write_ptr_wcnss_2->length);
+			driver->in_busy_wcnss_2 = 0;
 		}
 #ifdef CONFIG_DIAG_SDIO_PIPE
 		/* copy 9K data over SDIO */
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 4cf6d33..a77d825 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -271,7 +271,8 @@
 			queue_work(driver->diag_wq, &(driver->
 						diag_read_smd_qdsp_work));
 		}  else if (proc_num == WCNSS_DATA) {
-			driver->in_busy_wcnss = 0;
+			driver->in_busy_wcnss_1 = 0;
+			driver->in_busy_wcnss_2 = 0;
 			queue_work(driver->diag_wq, &(driver->
 				diag_read_smd_wcnss_work));
 		}
@@ -343,11 +344,21 @@
 
 void __diag_smd_wcnss_send_req(void)
 {
-	void *buf = driver->buf_in_wcnss;
-	int *in_busy_wcnss_ptr = &(driver->in_busy_wcnss);
-	struct diag_request *write_ptr_wcnss = driver->write_ptr_wcnss;
+	void *buf = NULL;
+	int *in_busy_wcnss_ptr = NULL;
+	struct diag_request *write_ptr_wcnss = NULL;
 
-	if ((!driver->in_busy_wcnss) && driver->ch_wcnss && buf) {
+	if (!driver->in_busy_wcnss_1) {
+		buf = driver->buf_in_wcnss_1;
+		write_ptr_wcnss = driver->write_ptr_wcnss_1;
+		in_busy_wcnss_ptr = &(driver->in_busy_wcnss_1);
+	} else if (!driver->in_busy_wcnss_2) {
+		buf = driver->buf_in_wcnss_2;
+		write_ptr_wcnss = driver->write_ptr_wcnss_2;
+		in_busy_wcnss_ptr = &(driver->in_busy_wcnss_2);
+	}
+
+	if (driver->ch_wcnss && buf) {
 		int r = smd_read_avail(driver->ch_wcnss);
 		if (r > IN_BUF_SIZE) {
 			if (r < MAX_IN_BUF_SIZE) {
@@ -1248,7 +1259,8 @@
 	driver->in_busy_2 = 0;
 	driver->in_busy_qdsp_1 = 0;
 	driver->in_busy_qdsp_2 = 0;
-	driver->in_busy_wcnss = 0;
+	driver->in_busy_wcnss_1 = 0;
+	driver->in_busy_wcnss_2 = 0;
 
 	/* Poll SMD channels to check for data*/
 	queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
@@ -1282,7 +1294,8 @@
 		driver->in_busy_2 = 1;
 		driver->in_busy_qdsp_1 = 1;
 		driver->in_busy_qdsp_2 = 1;
-		driver->in_busy_wcnss = 1;
+		driver->in_busy_wcnss_1 = 1;
+		driver->in_busy_wcnss_2 = 1;
 	}
 #ifdef CONFIG_DIAG_SDIO_PIPE
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
@@ -1314,8 +1327,13 @@
 		driver->in_busy_qdsp_2 = 0;
 		APPEND_DEBUG('P');
 		queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
-	} else if (buf == (void *)driver->buf_in_wcnss) {
-		driver->in_busy_wcnss = 0;
+	} else if (buf == driver->buf_in_wcnss_1) {
+		driver->in_busy_wcnss_1 = 0;
+		APPEND_DEBUG('r');
+		queue_work(driver->diag_wq,
+			 &(driver->diag_read_smd_wcnss_work));
+	} else if (buf == driver->buf_in_wcnss_2) {
+		driver->in_busy_wcnss_2 = 0;
 		APPEND_DEBUG('R');
 		queue_work(driver->diag_wq,
 			 &(driver->diag_read_smd_wcnss_work));
@@ -1568,11 +1586,17 @@
 		if (driver->buf_in_qdsp_2 == NULL)
 			goto err;
 	}
-	if (driver->buf_in_wcnss == NULL) {
-		driver->buf_in_wcnss = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
-		if (driver->buf_in_wcnss == NULL)
+	if (driver->buf_in_wcnss_1 == NULL) {
+		driver->buf_in_wcnss_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
+		if (driver->buf_in_wcnss_1 == NULL)
 			goto err;
 	}
+	if (driver->buf_in_wcnss_2 == NULL) {
+		driver->buf_in_wcnss_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
+		if (driver->buf_in_wcnss_2 == NULL)
+			goto err;
+	}
+
 	if (driver->buf_msg_mask_update == NULL) {
 		driver->buf_msg_mask_update = kzalloc(APPS_BUF_SIZE,
 								 GFP_KERNEL);
@@ -1657,12 +1681,19 @@
 		if (driver->write_ptr_qdsp_2 == NULL)
 			goto err;
 	}
-	if (driver->write_ptr_wcnss == NULL) {
-		driver->write_ptr_wcnss = kzalloc(
+	if (driver->write_ptr_wcnss_1 == NULL) {
+		driver->write_ptr_wcnss_1 = kzalloc(
 			sizeof(struct diag_request), GFP_KERNEL);
-		if (driver->write_ptr_wcnss == NULL)
+		if (driver->write_ptr_wcnss_1 == NULL)
 			goto err;
 	}
+	if (driver->write_ptr_wcnss_2 == NULL) {
+		driver->write_ptr_wcnss_2 = kzalloc(
+			sizeof(struct diag_request), GFP_KERNEL);
+		if (driver->write_ptr_wcnss_2 == NULL)
+			goto err;
+	}
+
 	if (driver->usb_read_ptr == NULL) {
 		driver->usb_read_ptr = kzalloc(
 			sizeof(struct diag_request), GFP_KERNEL);
@@ -1712,7 +1743,8 @@
 		kfree(driver->buf_in_2);
 		kfree(driver->buf_in_qdsp_1);
 		kfree(driver->buf_in_qdsp_2);
-		kfree(driver->buf_in_wcnss);
+		kfree(driver->buf_in_wcnss_1);
+		kfree(driver->buf_in_wcnss_2);
 		kfree(driver->buf_msg_mask_update);
 		kfree(driver->buf_log_mask_update);
 		kfree(driver->buf_event_mask_update);
@@ -1730,7 +1762,8 @@
 		kfree(driver->write_ptr_2);
 		kfree(driver->write_ptr_qdsp_1);
 		kfree(driver->write_ptr_qdsp_2);
-		kfree(driver->write_ptr_wcnss);
+		kfree(driver->write_ptr_wcnss_1);
+		kfree(driver->write_ptr_wcnss_2);
 		kfree(driver->usb_read_ptr);
 		kfree(driver->apps_rsp_buf);
 		kfree(driver->user_space_data);
@@ -1760,7 +1793,8 @@
 	kfree(driver->buf_in_2);
 	kfree(driver->buf_in_qdsp_1);
 	kfree(driver->buf_in_qdsp_2);
-	kfree(driver->buf_in_wcnss);
+	kfree(driver->buf_in_wcnss_1);
+	kfree(driver->buf_in_wcnss_2);
 	kfree(driver->buf_msg_mask_update);
 	kfree(driver->buf_log_mask_update);
 	kfree(driver->buf_event_mask_update);
@@ -1778,7 +1812,8 @@
 	kfree(driver->write_ptr_2);
 	kfree(driver->write_ptr_qdsp_1);
 	kfree(driver->write_ptr_qdsp_2);
-	kfree(driver->write_ptr_wcnss);
+	kfree(driver->write_ptr_wcnss_1);
+	kfree(driver->write_ptr_wcnss_2);
 	kfree(driver->usb_read_ptr);
 	kfree(driver->apps_rsp_buf);
 	kfree(driver->user_space_data);
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 7a08e50..de9e2c4 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -271,10 +271,11 @@
 					unsigned long iova_length,
 					unsigned long flags)
 {
-	unsigned long temp_phys, temp_iova;
 	struct iommu_domain *domain;
-	int i, ret = 0;
+	int ret = 0;
 	unsigned long extra;
+	int prot = ION_IS_CACHED(flags) ? 1 : 0;
+	struct scatterlist *sglist = 0;
 
 	data->mapped_size = iova_length;
 
@@ -300,32 +301,36 @@
 		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);
+	sglist = vmalloc(sizeof(*sglist));
+	if (!sglist)
+		goto out1;
 
-		if (ret) {
-			pr_err("%s: could not map %lx to %lx in domain %p\n",
-				__func__, temp_iova, temp_phys, domain);
-			goto out2;
-		}
+	sg_init_table(sglist, 1);
+	sglist->length = buffer->size;
+	sglist->offset = 0;
+	sglist->dma_address = buffer->priv_phys;
+
+	ret = iommu_map_range(domain, data->iova_addr, sglist,
+			      buffer->size, prot);
+	if (ret) {
+		pr_err("%s: could not map %lx in domain %p\n",
+			__func__, data->iova_addr, domain);
+		goto out1;
 	}
 
-	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
-		goto out2;
-
-	return 0;
-
+	if (extra) {
+		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, prot);
+		if (ret)
+			goto out2;
+	}
+	vfree(sglist);
+	return ret;
 
 out2:
-	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
-		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
-
+	iommu_unmap_range(domain, data->iova_addr, buffer->size);
 out1:
+	vfree(sglist);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 				data->mapped_size);
 
@@ -336,8 +341,6 @@
 
 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;
@@ -355,10 +358,7 @@
 		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));
-
+	iommu_unmap_range(domain, data->iova_addr, data->mapped_size);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 				data->mapped_size);
 
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 85c0534..7d99482 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -295,8 +295,7 @@
 	buffer->priv_phys = ION_CP_ALLOCATE_FAIL;
 }
 
-struct scatterlist *ion_cp_heap_map_dma(struct ion_heap *heap,
-					      struct ion_buffer *buffer)
+struct scatterlist *ion_cp_heap_create_sglist(struct ion_buffer *buffer)
 {
 	struct scatterlist *sglist;
 
@@ -312,6 +311,12 @@
 	return sglist;
 }
 
+struct scatterlist *ion_cp_heap_map_dma(struct ion_heap *heap,
+					      struct ion_buffer *buffer)
+{
+	return ion_cp_heap_create_sglist(buffer);
+}
+
 void ion_cp_heap_unmap_dma(struct ion_heap *heap,
 				 struct ion_buffer *buffer)
 {
@@ -570,10 +575,11 @@
 				unsigned long iova_length,
 				unsigned long flags)
 {
-	unsigned long temp_phys, temp_iova;
 	struct iommu_domain *domain;
-	int i, ret = 0;
+	int ret = 0;
 	unsigned long extra;
+	int prot = ION_IS_CACHED(flags) ? 1 : 0;
+	struct scatterlist *sglist = 0;
 
 	data->mapped_size = iova_length;
 
@@ -599,30 +605,33 @@
 		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;
-		}
+	sglist = ion_cp_heap_create_sglist(buffer);
+	if (IS_ERR_OR_NULL(sglist)) {
+		ret = -ENOMEM;
+		goto out1;
+	}
+	ret = iommu_map_range(domain, data->iova_addr, sglist,
+			      buffer->size, prot);
+	if (ret) {
+		pr_err("%s: could not map %lx in domain %p\n",
+			__func__, data->iova_addr, domain);
+		goto out1;
 	}
 
-	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
-		goto out2;
-
-	return 0;
+	if (extra) {
+		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, prot);
+		if (ret)
+			goto out2;
+	}
+	vfree(sglist);
+	return ret;
 
 out2:
-	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
-		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+	iommu_unmap_range(domain, data->iova_addr, buffer->size);
 out1:
+	if (!IS_ERR_OR_NULL(sglist))
+		vfree(sglist);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 				data->mapped_size);
 out:
@@ -631,8 +640,6 @@
 
 static void ion_cp_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;
@@ -650,10 +657,7 @@
 		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));
-
+	iommu_unmap_range(domain, data->iova_addr, data->mapped_size);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 				data->mapped_size);
 
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index e754496..baf0a66 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -33,6 +33,7 @@
 	struct page **pages;
 	int nrpages;
 	unsigned long size;
+	struct scatterlist *iommu_sglist;
 };
 
 static int ion_iommu_heap_allocate(struct ion_heap *heap,
@@ -56,11 +57,22 @@
 			ret = -ENOMEM;
 			goto err1;
 		}
+		data->iommu_sglist = vmalloc(sizeof(*data->iommu_sglist) *
+						data->nrpages);
+		if (!data->iommu_sglist) {
+			ret = -ENOMEM;
+			goto err1;
+		}
+
+		sg_init_table(data->iommu_sglist, data->nrpages);
 
 		for (i = 0; i < data->nrpages; i++) {
 			data->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
 			if (!data->pages[i])
 				goto err2;
+
+			sg_set_page(&data->iommu_sglist[i], data->pages[i],
+				    PAGE_SIZE, 0);
 		}
 
 
@@ -73,6 +85,9 @@
 
 
 err2:
+	vfree(data->iommu_sglist);
+	data->iommu_sglist = NULL;
+
 	for (i = 0; i < data->nrpages; i++) {
 		if (data->pages[i])
 			__free_page(data->pages[i]);
@@ -94,6 +109,9 @@
 	for (i = 0; i < data->nrpages; i++)
 		__free_page(data->pages[i]);
 
+	vfree(data->iommu_sglist);
+	data->iommu_sglist = NULL;
+
 	kfree(data->pages);
 	kfree(data);
 }
@@ -160,11 +178,11 @@
 					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;
+	int ret = 0;
 	unsigned long extra;
+	int prot = ION_IS_CACHED(flags) ? 1 : 0;
+	struct ion_iommu_priv_data *buffer_data = buffer->priv_virt;
 
 	BUG_ON(!msm_use_iommu());
 
@@ -186,36 +204,24 @@
 		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;
-		}
+	ret = iommu_map_range(domain, data->iova_addr,
+			      buffer_data->iommu_sglist, buffer->size, prot);
+	if (ret) {
+		pr_err("%s: could not map %lx in domain %p\n",
+			__func__, data->iova_addr, domain);
+		goto out1;
 	}
 
-
-	if (extra &&
-		msm_iommu_map_extra
-			(domain, temp_iova, extra, flags) < 0)
-		goto out2;
-
-	return 0;
-
+	if (extra) {
+		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, prot);
+		if (ret)
+			goto out2;
+	}
+	return ret;
 
 out2:
-	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
-		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
-
+	iommu_unmap_range(domain, data->iova_addr, buffer->size);
 out1:
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 				buffer->size);
@@ -227,8 +233,6 @@
 
 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;
@@ -245,10 +249,7 @@
 		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));
-
+	iommu_unmap_range(domain, data->iova_addr, data->mapped_size);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 				data->mapped_size);
 
@@ -293,30 +294,13 @@
 static struct scatterlist *ion_iommu_heap_map_dma(struct ion_heap *heap,
 					      struct ion_buffer *buffer)
 {
-	struct scatterlist *sglist = NULL;
-	if (buffer->priv_virt) {
-		struct ion_iommu_priv_data *data = buffer->priv_virt;
-		unsigned int i;
-
-		if (!data->nrpages)
-			return NULL;
-
-		sglist = vmalloc(sizeof(*sglist) * data->nrpages);
-		if (!sglist)
-			return ERR_PTR(-ENOMEM);
-
-		sg_init_table(sglist, data->nrpages);
-		for (i = 0; i < data->nrpages; ++i)
-			sg_set_page(&sglist[i], data->pages[i], PAGE_SIZE, 0);
-	}
-	return sglist;
+	struct ion_iommu_priv_data *data = buffer->priv_virt;
+	return data->iommu_sglist;
 }
 
 static void ion_iommu_heap_unmap_dma(struct ion_heap *heap,
 				 struct ion_buffer *buffer)
 {
-	if (buffer->sglist)
-		vfree(buffer->sglist);
 }
 
 static struct ion_heap_ops iommu_heap_ops = {
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 316740e..bc288e7 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -104,8 +104,6 @@
 
 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;
@@ -123,10 +121,7 @@
 		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));
-
+	iommu_unmap_range(domain, data->iova_addr, data->mapped_size);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 				data->mapped_size);
 
@@ -206,11 +201,15 @@
 				unsigned long iova_length,
 				unsigned long flags)
 {
-	int ret, i;
-	unsigned long temp_iova;
+	int ret = 0, i;
 	struct iommu_domain *domain;
-	void *temp_phys;
 	unsigned long extra;
+	unsigned long extra_iova_addr;
+	struct page *page;
+	int npages = buffer->size >> PAGE_SHIFT;
+	void *vaddr = buffer->priv_virt;
+	struct scatterlist *sglist = 0;
+	int prot = ION_IS_CACHED(flags) ? 1 : 0;
 
 	if (!ION_IS_CACHED(flags))
 		return -EINVAL;
@@ -236,35 +235,46 @@
 		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;
-		}
+	sglist = vmalloc(sizeof(*sglist) * npages);
+	if (!sglist) {
+		ret = -ENOMEM;
+		goto out1;
 	}
 
-	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
-		goto out2;
+	sg_init_table(sglist, npages);
+	for (i = 0; i < npages; i++) {
+		page = vmalloc_to_page(vaddr);
+		if (!page)
+			goto out1;
+		sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
+		vaddr += PAGE_SIZE;
+	}
 
-	return 0;
+	ret = iommu_map_range(domain, data->iova_addr, sglist,
+			      buffer->size, prot);
+
+	if (ret) {
+		pr_err("%s: could not map %lx in domain %p\n",
+			__func__, data->iova_addr, domain);
+		goto out1;
+	}
+
+	extra_iova_addr = data->iova_addr + buffer->size;
+	if (extra) {
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, prot);
+		if (ret)
+			goto out2;
+	}
+	vfree(sglist);
+	return ret;
 
 out2:
-	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
-		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
-
+	iommu_unmap_range(domain, data->iova_addr, buffer->size);
 out1:
+	vfree(sglist);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
-						data->mapped_size);
+				data->mapped_size);
 out:
 	return ret;
 }
@@ -408,10 +418,12 @@
 				unsigned long iova_length,
 				unsigned long flags)
 {
-	int ret, i;
+	int ret = 0;
 	struct iommu_domain *domain;
-	unsigned long temp_phys, temp_iova;
 	unsigned long extra;
+	int prot = ION_IS_CACHED(flags) ? 1 : 0;
+	struct scatterlist *sglist = 0;
+	struct page *page = 0;
 
 	if (!ION_IS_CACHED(flags))
 		return -EINVAL;
@@ -438,30 +450,36 @@
 		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);
+	page = virt_to_page(buffer->vaddr);
 
-		if (ret) {
-			pr_err("%s: could not map %lx to %lx in domain %p\n",
-				__func__, temp_iova, temp_phys, domain);
-			goto out2;
-		}
+	sglist = vmalloc(sizeof(*sglist));
+	if (!sglist)
+		goto out1;
+
+	sg_init_table(sglist, 1);
+	sg_set_page(sglist, page, buffer->size, 0);
+
+	ret = iommu_map_range(domain, data->iova_addr, sglist,
+			      buffer->size, prot);
+	if (ret) {
+		pr_err("%s: could not map %lx in domain %p\n",
+			__func__, data->iova_addr, domain);
+		goto out1;
 	}
 
-	if (extra && (msm_iommu_map_extra(domain, temp_iova, extra, flags) < 0))
-		goto out2;
-
-	return 0;
+	if (extra) {
+		unsigned long extra_iova_addr = data->iova_addr + buffer->size;
+		ret = msm_iommu_map_extra(domain, extra_iova_addr, extra, prot);
+		if (ret)
+			goto out2;
+	}
+	vfree(sglist);
+	return ret;
 out2:
-	for ( ; i < buffer->size; i += SZ_4K, temp_iova -= SZ_4K)
-		iommu_unmap(domain, temp_iova, get_order(SZ_4K));
+	iommu_unmap_range(domain, data->iova_addr, buffer->size);
 
 out1:
+	vfree(sglist);
 	msm_free_iova_address(data->iova_addr, domain_num, partition_num,
 						data->mapped_size);
 out:
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 970f377..4f5c783 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -249,7 +249,7 @@
 
 /* Bit flags for RBBM_CTL */
 #define RBBM_RBBM_CTL_RESET_PWR_CTR1  (1 << 1)
-#define RBBM_RBBM_CTL_ENABLE_PWR_CTR1  (17 << 1)
+#define RBBM_RBBM_CTL_ENABLE_PWR_CTR1  (1 << 17)
 
 /* Various flags used by the context switch code */
 
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 3db397b..d7a104c 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -398,7 +398,7 @@
 	* adreno 22x gpus are indicated by coreid 2,
 	* but REG_RBBM_PERIPHID1 always contains 0 for this field
 	*/
-	if (cpu_is_msm8960() || cpu_is_msm8x60() || cpu_is_msm8930())
+	if (cpu_is_msm8960() || cpu_is_msm8x60())
 		chipid = 2 << 24;
 	else
 		chipid = (coreid & 0xF) << 24;
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index f31d120..52c2ab1 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1907,7 +1907,7 @@
 	adreno_regwrite(device, REG_SQ_VS_PROGRAM, 0x00000000);
 	adreno_regwrite(device, REG_SQ_PS_PROGRAM, 0x00000000);
 
-	if (cpu_is_msm8960() || cpu_is_msm8930())
+	if (cpu_is_msm8960())
 		adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0x200);
 	else
 		adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 37d18bc..1b0a7bc 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1195,6 +1195,8 @@
 	struct kgsl_mem_entry *entry = NULL;
 	struct vm_area_struct *vma;
 
+	KGSL_DEV_ERR_ONCE(dev_priv->device, "IOCTL_KGSL_SHAREDMEM_FROM_VMALLOC"
+			" is deprecated\n");
 	if (!kgsl_mmu_enabled())
 		return -ENODEV;
 
@@ -1637,6 +1639,8 @@
 		break;
 
 	case KGSL_USER_MEM_TYPE_ADDR:
+		KGSL_DEV_ERR_ONCE(dev_priv->device, "User mem type "
+				"KGSL_USER_MEM_TYPE_ADDR is deprecated\n");
 		if (!kgsl_mmu_enabled()) {
 			KGSL_DRV_ERR(dev_priv->device,
 				"Cannot map paged memory with the "
diff --git a/drivers/gpu/msm/kgsl_log.h b/drivers/gpu/msm/kgsl_log.h
index 9fafcf4..6fd28ab 100644
--- a/drivers/gpu/msm/kgsl_log.h
+++ b/drivers/gpu/msm/kgsl_log.h
@@ -48,6 +48,16 @@
 
 #define KGSL_LOG_DUMP(_dev, fmt, args...)	dev_err(_dev->dev, fmt, ##args)
 
+#define KGSL_DEV_ERR_ONCE(_dev, fmt, args...) \
+({ \
+	static bool kgsl_dev_err_once; \
+							\
+	if (!kgsl_dev_err_once) { \
+		kgsl_dev_err_once = true; \
+		dev_crit(_dev->dev, "|%s| " fmt, __func__, ##args); \
+	} \
+})
+
 #define KGSL_DRV_INFO(_dev, fmt, args...) \
 KGSL_LOG_INFO(_dev->dev, _dev->drv_log, fmt, ##args)
 #define KGSL_DRV_WARN(_dev, fmt, args...) \
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index a03e530..8ccd462 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -699,7 +699,7 @@
 		}
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
-		kgsl_pwrctrl_set_state(device, KGSL_STATE_NAP);
+		kgsl_pwrctrl_set_state(device, device->requested_state);
 		if (device->idle_wakelock.name)
 			wake_unlock(&device->idle_wakelock);
 	case KGSL_STATE_NAP:
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index 931ef48..eef80d3 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -180,7 +180,7 @@
 	struct tz_priv *priv;
 
 	/* Trustzone is only valid for some SOCs */
-	if (!(cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_msm8930()))
+	if (!(cpu_is_msm8x60() || cpu_is_msm8960()))
 		return -EINVAL;
 
 	priv = pwrscale->priv = kzalloc(sizeof(struct tz_priv), GFP_KERNEL);
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 46199d8..d1bfc07 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.c
@@ -98,6 +98,37 @@
 
 #define PM8XXX_LED_PWM_FLAGS	(PM_PWM_LUT_LOOP | PM_PWM_LUT_RAMP_UP)
 
+#define LED_MAP(_version, _kb, _led0, _led1, _led2, _flash_led0, _flash_led1, \
+	_wled)\
+	{\
+		.version = _version,\
+		.supported = _kb << PM8XXX_ID_LED_KB_LIGHT | \
+			_led0 << PM8XXX_ID_LED_0 | _led1 << PM8XXX_ID_LED_1 | \
+			_led2 << PM8XXX_ID_LED_2  | \
+			_flash_led0 << PM8XXX_ID_FLASH_LED_0 | \
+			_flash_led1 << PM8XXX_ID_FLASH_LED_1 | \
+			_wled << PM8XXX_ID_WLED, \
+	}
+
+/**
+ * supported_leds - leds supported for each PMIC version
+ * @version - version of PMIC
+ * @supported - which leds are supported on version
+ */
+
+struct supported_leds {
+	enum pm8xxx_version version;
+	u32 supported;
+};
+
+static const struct supported_leds led_map[] = {
+	LED_MAP(PM8XXX_VERSION_8058, 1, 1, 1, 1, 1, 1, 0),
+	LED_MAP(PM8XXX_VERSION_8921, 1, 1, 1, 1, 1, 1, 0),
+	LED_MAP(PM8XXX_VERSION_8018, 1, 0, 0, 0, 0, 0, 0),
+	LED_MAP(PM8XXX_VERSION_8922, 0, 0, 0, 0, 1, 1, 1),
+	LED_MAP(PM8XXX_VERSION_8038, 0, 0, 0, 0, 0, 0, 1),
+};
+
 /**
  * struct pm8xxx_led_data - internal led data structure
  * @led_classdev - led class device
@@ -639,7 +670,9 @@
 	struct led_info *curr_led;
 	struct pm8xxx_led_data *led, *led_dat;
 	struct pm8xxx_led_config *led_cfg;
-	int rc, i;
+	enum pm8xxx_version version;
+	bool found = false;
+	int rc, i, j;
 
 	if (pdata == NULL) {
 		dev_err(&pdev->dev, "platform data not supplied\n");
@@ -674,8 +707,26 @@
 
 		if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) &&
 				(led_dat->id < PM8XXX_ID_MAX))) {
-			dev_err(&pdev->dev, "invalid LED ID (%d) specified\n",
-						 led_dat->id);
+			dev_err(&pdev->dev, "invalid LED ID(%d) specified\n",
+				led_dat->id);
+			rc = -EINVAL;
+			goto fail_id_check;
+
+		}
+
+		found = false;
+		version = pm8xxx_get_version(pdev->dev.parent);
+		for (j = 0; j < ARRAY_SIZE(led_map); j++) {
+			if (version == led_map[j].version
+			&& (led_map[j].supported & (1 << led_dat->id))) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			dev_err(&pdev->dev, "invalid LED ID(%d) specified\n",
+				led_dat->id);
 			rc = -EINVAL;
 			goto fail_id_check;
 		}
diff --git a/drivers/media/video/msm/gemini/msm_gemini_core.c b/drivers/media/video/msm/gemini/msm_gemini_core.c
index 480500b..45d3937 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_core.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -71,7 +71,6 @@
 	for (i = 0; i < 2; i++) {
 		if (we_pingpong_buf.buf_status[i] && release_buf)
 			msm_gemini_platform_p2v(we_pingpong_buf.buf[i].file,
-					&we_pingpong_buf.buf[i].msm_buffer,
 					&we_pingpong_buf.buf[i].handle);
 		we_pingpong_buf.buf_status[i] = 0;
 	}
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.h b/drivers/media/video/msm/gemini/msm_gemini_hw.h
index 3c2fc6a..e1702a5 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -27,8 +27,6 @@
 	uint32_t cbcr_buffer_addr;
 	uint32_t cbcr_len;
 	uint32_t num_of_mcu_rows;
-	struct msm_mapped_buffer *msm_buffer;
-	int *subsystem_id;
 	struct ion_handle *handle;
 };
 
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.c b/drivers/media/video/msm/gemini/msm_gemini_platform.c
index e81215e..ee0ff2f 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_platform.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -28,14 +28,10 @@
 struct ion_client *gemini_client;
 
 void msm_gemini_platform_p2v(struct file  *file,
-				struct msm_mapped_buffer **msm_buffer,
 				struct ion_handle **ionhandle)
 {
-	if (msm_subsystem_unmap_buffer(
-		(struct msm_mapped_buffer *)*msm_buffer) < 0)
-		pr_err("%s: umapped stat memory\n",  __func__);
-	*msm_buffer = NULL;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL);
 	ion_free(gemini_client, *ionhandle);
 	*ionhandle = NULL;
 #elif CONFIG_ANDROID_PMEM
@@ -44,18 +40,18 @@
 }
 
 uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p,
-				struct msm_mapped_buffer **msm_buffer,
-				int *subsys_id, struct ion_handle **ionhandle)
+				struct ion_handle **ionhandle)
 {
 	unsigned long paddr;
 	unsigned long size;
 	int rc;
-	int flags;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	*ionhandle = ion_import_fd(gemini_client, fd);
 	if (IS_ERR_OR_NULL(*ionhandle))
 		return 0;
-	rc = ion_phys(gemini_client, *ionhandle, &paddr, (size_t *)&size);
+
+	rc = ion_map_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL,
+			SZ_4K, 0, &paddr, (unsigned long *)&size, UNCACHED, 0);
 #elif CONFIG_ANDROID_PMEM
 	unsigned long kvstart;
 	rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p);
@@ -67,31 +63,21 @@
 	if (rc < 0) {
 		GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd,
 			rc);
-		return 0;
+		goto error1;
 	}
 
 	/* validate user input */
 	if (len > size) {
 		GMN_PR_ERR("%s: invalid offset + len\n", __func__);
-		return 0;
+		goto error1;
 	}
 
-	flags = MSM_SUBSYSTEM_MAP_IOVA;
-	*subsys_id = MSM_SUBSYSTEM_CAMERA;
-	*msm_buffer = msm_subsystem_map_buffer(paddr, size,
-					flags, subsys_id, 1);
-	if (IS_ERR((void *)*msm_buffer)) {
-		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		ion_free(gemini_client, *ionhandle);
-		*ionhandle = NULL;
-#elif CONFIG_ANDROID_PMEM
-		put_pmem_file(*file_p);
-#endif
-		return 0;
-	}
-	paddr = ((struct msm_mapped_buffer *)*msm_buffer)->iova[0];
 	return paddr;
+error1:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(gemini_client, *ionhandle);
+#endif
+	return 0;
 }
 
 int msm_gemini_platform_init(struct platform_device *pdev,
diff --git a/drivers/media/video/msm/gemini/msm_gemini_platform.h b/drivers/media/video/msm/gemini/msm_gemini_platform.h
index c54d7df..4542129 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_platform.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_platform.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -17,11 +17,9 @@
 #include <linux/platform_device.h>
 #include <linux/ion.h>
 void msm_gemini_platform_p2v(struct file  *file,
-				struct msm_mapped_buffer **msm_buffer,
 				struct ion_handle **ionhandle);
 uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file,
-				struct msm_mapped_buffer **msm_buffer,
-				int *subsys_id, struct ion_handle **ionhandle);
+				struct ion_handle **ionhandle);
 
 int msm_gemini_platform_clk_enable(void);
 int msm_gemini_platform_clk_disable(void);
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.c b/drivers/media/video/msm/gemini/msm_gemini_sync.c
index f035ad6..fe7c99f 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -151,9 +151,8 @@
 		buf_p = msm_gemini_q_out(q_p);
 		if (buf_p) {
 			msm_gemini_platform_p2v(buf_p->file,
-				&buf_p->msm_buffer, &buf_p->handle);
+				&buf_p->handle);
 			GMN_DBG("%s:%d] %s\n", __func__, __LINE__, q_p->name);
-			kfree(buf_p->subsystem_id);
 			kfree(buf_p);
 		}
 	} while (buf_p);
@@ -317,9 +316,7 @@
 	}
 
 	buf_cmd = buf_p->vbuf;
-	msm_gemini_platform_p2v(buf_p->file, &buf_p->msm_buffer,
-				&buf_p->handle);
-	kfree(buf_p->subsystem_id);
+	msm_gemini_platform_p2v(buf_p->file, &buf_p->handle);
 	kfree(buf_p);
 
 	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
@@ -361,18 +358,10 @@
 	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__, (int) buf_cmd.vaddr,
 		buf_cmd.y_len);
 
-	buf_p->subsystem_id = kmalloc(sizeof(int), GFP_ATOMIC);
-	if (!buf_p->subsystem_id) {
-		GMN_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
-		kfree(buf_p);
-		return -ENOMEM;
-	}
 	buf_p->y_buffer_addr = msm_gemini_platform_v2p(buf_cmd.fd,
-		buf_cmd.y_len, &buf_p->file, &buf_p->msm_buffer,
-		buf_p->subsystem_id, &buf_p->handle);
+		buf_cmd.y_len, &buf_p->file, &buf_p->handle);
 	if (!buf_p->y_buffer_addr) {
 		GMN_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		kfree(buf_p->subsystem_id);
 		kfree(buf_p);
 		return -1;
 	}
@@ -437,10 +426,8 @@
 	buf_cmd = buf_p->vbuf;
 	if (pgmn_dev->op_mode == MSM_GEMINI_MODE_OFFLINE_ENCODE ||
 		pgmn_dev->op_mode == MSM_GEMINI_MODE_OFFLINE_ROTATION) {
-		msm_gemini_platform_p2v(buf_p->file, &buf_p->msm_buffer,
-			&buf_p->handle);
+		msm_gemini_platform_p2v(buf_p->file, &buf_p->handle);
 	}
-	kfree(buf_p->subsystem_id);
 	kfree(buf_p);
 
 	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
@@ -481,19 +468,12 @@
 	GMN_DBG("%s:%d] 0x%08x %d\n", __func__, __LINE__,
 		(int) buf_cmd.vaddr, buf_cmd.y_len);
 
-	buf_p->subsystem_id = kmalloc(sizeof(int), GFP_ATOMIC);
-	if (!buf_p->subsystem_id) {
-		GMN_PR_ERR("%s:%d] no mem\n", __func__, __LINE__);
-		kfree(buf_p);
-		return -ENOMEM;
-	}
 	if (pgmn_dev->op_mode == MSM_GEMINI_MODE_REALTIME_ENCODE) {
 		buf_p->y_buffer_addr    = buf_cmd.y_off;
 	} else {
 	buf_p->y_buffer_addr    = msm_gemini_platform_v2p(buf_cmd.fd,
 		buf_cmd.y_len + buf_cmd.cbcr_len, &buf_p->file,
-			&buf_p->msm_buffer, buf_p->subsystem_id, &buf_p->handle)
-			+ buf_cmd.offset;
+		&buf_p->handle)	+ buf_cmd.offset;
 	}
 	buf_p->y_len          = buf_cmd.y_len;
 
@@ -507,7 +487,6 @@
 
 	if (!buf_p->y_buffer_addr || !buf_p->cbcr_buffer_addr) {
 		GMN_PR_ERR("%s:%d] v2p wrong\n", __func__, __LINE__);
-		kfree(buf_p->subsystem_id);
 		kfree(buf_p);
 		return -1;
 	}
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 628fa62..001e02a 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -194,7 +194,8 @@
 	info.pxlcode = pcam->usr_fmts[0].pxlcode;
 	info.flashtype = sdata->flash_type; /* two flash_types here? */
 	info.camera_type = sdata->camera_type;
-	info.sensor_type = 0; /* need to add YUV/SOC in probing */
+	/* sensor_type needed to add YUV/SOC in probing */
+	info.sensor_type = sdata->sensor_type;
 	info.mount_angle = sdata->sensor_platform_info->mount_angle;
 	/* copy back to user space */
 	if (copy_to_user((void *)arg,
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 54b4efb..4f7e5d2 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -26,7 +26,6 @@
 #include <media/v4l2-device.h>
 
 #include <linux/android_pmem.h>
-#include <mach/msm_subsystem_map.h>
 
 #include "msm.h"
 
@@ -120,7 +119,6 @@
 	struct msm_pmem_info *info, struct ion_client *client)
 {
 	unsigned long paddr;
-	unsigned int flags;
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned long kvstart;
 	struct file *file;
@@ -137,7 +135,9 @@
 	region->handle = ion_import_fd(client, info->fd);
 	if (IS_ERR_OR_NULL(region->handle))
 		goto out1;
-	ion_phys(client, region->handle, &paddr, (size_t *)&len);
+	if (ion_map_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL,
+				  SZ_4K, 0, &paddr, &len, UNCACHED, 0) < 0)
+		goto out2;
 #elif CONFIG_ANDROID_PMEM
 	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
 	if (rc < 0) {
@@ -155,13 +155,13 @@
 		info->len = len;
 	rc = check_pmem_info(info, len);
 	if (rc < 0)
-		goto out2;
+		goto out3;
 	paddr += info->offset;
 	len = info->len;
 
 	if (check_overlap(ptype, paddr, len) < 0) {
 		rc = -EINVAL;
-		goto out2;
+		goto out3;
 	}
 
 	CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n",
@@ -169,16 +169,6 @@
 		(unsigned long)info->vaddr);
 
 	INIT_HLIST_NODE(&region->list);
-	flags = MSM_SUBSYSTEM_MAP_IOVA;
-	region->subsys_id = MSM_SUBSYSTEM_CAMERA;
-	region->msm_buffer = msm_subsystem_map_buffer(paddr, len,
-					flags, &(region->subsys_id), 1);
-	if (IS_ERR((void *)region->msm_buffer)) {
-		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
-		rc = PTR_ERR((void *)region->msm_buffer);
-		goto out2;
-	}
-	paddr = region->msm_buffer->iova[0];
 	region->paddr = paddr;
 	region->len = len;
 	memcpy(&region->info, info, sizeof(region->info));
@@ -188,8 +178,12 @@
 	hlist_add_head(&(region->list), ptype);
 
 	return 0;
-out2:
+out3:
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL);
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+out2:
 	ion_free(client, region->handle);
 #elif CONFIG_ANDROID_PMEM
 	put_pmem_file(region->file);
@@ -248,12 +242,9 @@
 				pinfo->vaddr == region->info.vaddr &&
 				pinfo->fd == region->info.fd) {
 				hlist_del(node);
-				if (msm_subsystem_unmap_buffer
-					(region->msm_buffer) < 0)
-					pr_err(
-					"%s: unmapped stat memory\n",
-				__func__);
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_unmap_iommu(client, region->handle,
+					CAMERA_DOMAIN, GEN_POOL);
 				ion_free(client, region->handle);
 #else
 				put_pmem_file(region->file);
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index a332fba..af27a56 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -292,7 +292,8 @@
 		"VFE_DEMOSAICv3_BPC_UPDATE"},
 	{VFE_CMD_XBAR_CFG, VFE_MAX, VFE_MAX},
 	{VFE_CMD_MODULE_CFG, VFE_MAX, VFE_MAX},
-	{VFE_CMD_ZSL, VFE_MAX, VFE_MAX},
+	{VFE_CMD_ZSL, VFE_START, QDSP_CMDQUEUE,
+			"VFE_CMD_ZSL", "VFE_START"},
 	{VFE_CMD_LINEARIZATION_UPDATE, VFE_MAX, VFE_MAX},
 	{VFE_CMD_DEMOSAICV3_ABF_UPDATE, VFE_DEMOSAICv3_ABF_CFG,
 		QDSP_TABLEQUEUE, "VFE_CMD_DEMOSAICV3_ABF_UPDATE",
@@ -452,6 +453,75 @@
 							y_phy, cbcr_phy);
 			break;
 		case MSG_OUTPUT1:
+			if (op_mode & SNAPSHOT_MASK_MODE) {
+				kfree(data);
+				return;
+			} else {
+				free_buf = vfe2x_check_free_buffer(
+							VFE_MSG_OUTPUT_IRQ,
+							VFE_MSG_OUTPUT_SECONDARY
+							);
+				CDBG("free_buf = %x\n",
+						(unsigned int) free_buf);
+				if (free_buf) {
+					fack.header = VFE_OUTPUT1_ACK;
+
+					fack.output2newybufferaddress =
+						(void *)(free_buf->ch_paddr[0]);
+
+					fack.output2newcbcrbufferaddress =
+						(void *)(free_buf->ch_paddr[1]);
+
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+							cmd_data, len);
+			      } else {
+					fack.header = VFE_OUTPUT1_ACK;
+					fack.output2newybufferaddress =
+					(void *)
+				((struct vfe_endframe *)data)->y_address;
+					fack.output2newcbcrbufferaddress =
+					(void *)
+				((struct vfe_endframe *)data)->cbcr_address;
+					cmd_data = &fack;
+					len = sizeof(fack);
+					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+						cmd_data, len);
+				}
+			}
+			y_phy = ((struct vfe_endframe *)data)->y_address;
+			cbcr_phy = ((struct vfe_endframe *)data)->cbcr_address;
+
+
+			CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
+				 y_phy, cbcr_phy);
+			if (free_buf) {
+				for (i = 0; i < 3; i++) {
+					if (vfe2x_ctrl->free_buf.buf[i].
+							ch_paddr[0] == y_phy) {
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[0] =
+							free_buf->ch_paddr[0];
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[1] =
+							free_buf->ch_paddr[1];
+						break;
+					}
+				}
+				if (i == 3)
+					CDBG("Address doesnt match\n");
+			}
+			memcpy(((struct vfe_frame_extra *)extdata),
+				&((struct vfe_endframe *)data)->extra,
+				sizeof(struct vfe_frame_extra));
+
+			vfe2x_ctrl->vfeFrameId =
+				((struct vfe_frame_extra *)extdata)->frame_id;
+			vfe_send_outmsg(&vfe2x_ctrl->subdev,
+						MSG_ID_OUTPUT_SECONDARY,
+						y_phy, cbcr_phy);
+			break;
 		case MSG_OUTPUT2:
 			if (op_mode & SNAPSHOT_MASK_MODE) {
 				kfree(data);
@@ -601,6 +671,7 @@
 	}
 	if (MSG_TABLE_CMD_ACK == id) {
 		spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+		vfe2x_ctrl->tableack_pending = 0;
 		if (list_empty(&vfe2x_ctrl->table_q)) {
 			if (vfe2x_ctrl->start_pending) {
 				CDBG("Send START\n");
@@ -633,14 +704,12 @@
 						cmd_data, len);
 				vfe2x_ctrl->update_pending = 0;
 			}
-			vfe2x_ctrl->tableack_pending = 0;
 			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
 			return;
 		}
 		table_pending = list_first_entry(&vfe2x_ctrl->table_q,
 					struct table_cmd, list);
 		if (!table_pending) {
-			vfe2x_ctrl->tableack_pending = 0;
 			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
 			return;
 		}
@@ -673,16 +742,32 @@
 
 	if (mode == OUTPUT_SEC) {
 		/* Thumbnail */
-		ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
-		ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
-		ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
-		ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
-		bptr = &ao->output1buffer3_y_phy;
-		for (cnt = 0; cnt < 6; cnt++) {
-			*bptr = ad->pong.ch_paddr[0];
-			bptr++;
-			*bptr = ad->pong.ch_paddr[1];
-			bptr++;
+		if (vfe2x_ctrl->zsl_mode) {
+			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+			ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+			ao->output2buffer3_y_phy = ad->free_buf.ch_paddr[0];
+			ao->output2buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
+			bptr = &ao->output2buffer4_y_phy;
+			for (cnt = 0; cnt < 5; cnt++) {
+				*bptr = ad->pong.ch_paddr[0];
+				bptr++;
+				*bptr = ad->pong.ch_paddr[1];
+				bptr++;
+			}
+		} else {
+			ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
+			ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+			ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
+			ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+			bptr = &ao->output1buffer3_y_phy;
+			for (cnt = 0; cnt < 6; cnt++) {
+				*bptr = ad->pong.ch_paddr[0];
+				bptr++;
+				*bptr = ad->pong.ch_paddr[1];
+				bptr++;
+			}
 		}
 	} else if (mode == OUTPUT_PRIM && o_mode != SNAPSHOT_MASK_MODE) {
 		/* Preview */
@@ -775,8 +860,13 @@
 		else if (path == VFE_MSG_OUTPUT_SECONDARY)
 			outch = &vfe2x_ctrl->thumb;
 	} else {
-		if (path == VFE_MSG_OUTPUT_PRIMARY)
-			outch = &vfe2x_ctrl->prev;
+		if (path == VFE_MSG_OUTPUT_PRIMARY) {
+			if (vfe2x_ctrl->zsl_mode)
+				outch = &vfe2x_ctrl->zsl_prim;
+			else
+				outch = &vfe2x_ctrl->prev;
+		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
+				outch = &vfe2x_ctrl->zsl_sec;
 	}
 	if (outch->free_buf.ch_paddr[0])
 		return &outch->free_buf;
@@ -797,8 +887,13 @@
 		else if (path == VFE_MSG_OUTPUT_SECONDARY)
 			outch = &vfe2x_ctrl->thumb;
 	} else {
-		if (path == VFE_MSG_OUTPUT_PRIMARY)
-			outch = &vfe2x_ctrl->prev;
+		if (path == VFE_MSG_OUTPUT_PRIMARY) {
+			if (vfe2x_ctrl->zsl_mode)
+				outch = &vfe2x_ctrl->zsl_prim;
+			else
+				outch = &vfe2x_ctrl->prev;
+		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
+			outch = &vfe2x_ctrl->zsl_sec;
 	}
 	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
 		/* Configure Preview Ping Pong */
@@ -823,8 +918,13 @@
 		else if (path == VFE_MSG_OUTPUT_PRIMARY)
 			ch = &vfe2x_ctrl->snap;
 	} else {
-		if (path == VFE_MSG_OUTPUT_PRIMARY)
-			ch = &vfe2x_ctrl->prev;
+		if (path == VFE_MSG_OUTPUT_PRIMARY) {
+			if (vfe2x_ctrl->zsl_mode)
+				ch = &vfe2x_ctrl->zsl_prim;
+			else
+				ch = &vfe2x_ctrl->prev;
+		} else if (path == VFE_MSG_OUTPUT_SECONDARY)
+			ch = &vfe2x_ctrl->zsl_sec;
 	}
 
 	BUG_ON(ch == NULL);
@@ -1121,6 +1221,7 @@
 			case VFE_CMD_START:
 			case VFE_CMD_CAPTURE:
 			case VFE_CMD_CAPTURE_RAW:
+			case VFE_CMD_ZSL:
 				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
 									flags);
 				if ((!list_empty(&vfe2x_ctrl->table_q)) ||
@@ -1185,6 +1286,7 @@
 	case CMD_AXI_CFG_SEC: {
 		CDBG("CMD_AXI_CFG_SEC\n");
 		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 0;
 		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
 		if (!axio) {
 			pr_err("NULL axio\n");
@@ -1237,6 +1339,7 @@
 	case CMD_AXI_CFG_PRIM: {
 		CDBG("CMD_AXI_CFG_PRIM : %d\n", op_mode);
 		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 0;
 		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
 		if (!axio) {
 			pr_err("NULL axio\n");
@@ -1299,9 +1402,74 @@
 		cmd_data = axio;
 	}
 		break;
+	case CMD_AXI_CFG_ZSL: {
+		CDBG("CMD_AXI_CFG_ZSL: %d\n", op_mode);
+		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 1;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			pr_err("NULL axio\n");
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			pr_err("copy_from_user failed\n");
+			rc = -EFAULT;
+			goto config_done;
+		}
+		if (!vfe2x_ctrl->reconfig_vfe) {
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_PREVIEW,
+						VFE_MSG_OUTPUT_PRIMARY);
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_PREVIEW,
+						VFE_MSG_OUTPUT_SECONDARY);
+			if (rc < 0) {
+				pr_err("%s error configuring pingpong buffers"
+					" for preview", __func__);
+				rc = -EINVAL;
+				goto config_done;
+			}
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+				free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+		} else {
+			vfe2x_ctrl->prev.ping.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[0];
+			vfe2x_ctrl->prev.ping.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[1];
+			vfe2x_ctrl->prev.pong.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[0];
+			vfe2x_ctrl->prev.pong.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[1];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[0];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[1];
+			vfe2x_ctrl->reconfig_vfe = 0;
+		}
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->zsl_prim, axio);
+		vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->zsl_sec, axio);
+		cmd_data = axio;
+	}
+		break;
 	case CMD_AXI_CFG_SEC|CMD_AXI_CFG_PRIM: {
 		CDBG("CMD_AXI_CFG_SEC|PRIM\n");
 		raw_mode = 0;
+		vfe2x_ctrl->zsl_mode = 0;
 		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
 		if (!axio) {
 			pr_err("NULL axio\n");
@@ -1440,20 +1608,22 @@
 		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
 	} else {
 		if (queue == QDSP_TABLEQUEUE) {
-			CDBG("sending table cmd\n");
 			spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+			CDBG("sending table cmd\n");
+			vfe2x_ctrl->tableack_pending = 1;
 			rc = msm_adsp_write(vfe_mod, queue,
 				cmd_data, vfecmd.length + 4);
-			vfe2x_ctrl->tableack_pending = 1;
 			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
 		} else {
-			CDBG("send n-table cmd\n");
 			if (*(uint32_t *)cmd_data == VFE_OUTPUT2_ACK) {
 				uint32_t *ptr = cmd_data;
 				CDBG("%x %x %x\n", ptr[0], ptr[1], ptr[2]);
 			}
+			spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+			CDBG("send n-table cmd\n");
 			rc = msm_adsp_write(vfe_mod, queue,
 				cmd_data, vfecmd.length + 4);
+			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
 			CDBG("%x\n", vfecmd.length + 4);
 		}
 	}
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
index 2b77159..2f2d3c6 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
@@ -85,6 +85,10 @@
 	struct buf_info raw;
 	struct buf_info thumb;
 	struct prev_free_buf_info free_buf;
+	struct buf_info zsl_prim;
+	struct buf_info zsl_sec;
+	struct prev_free_buf_info zsl_free_buf[2];
+
 
 	spinlock_t  table_lock;
 	struct list_head table_q;
@@ -106,6 +110,7 @@
 	struct clk *vfe_clk[3];
 	spinlock_t  sd_notify_lock;
 	uint32_t    reconfig_vfe;
+	uint32_t    zsl_mode;
 } __packed;
 
 struct vfe_frame_extra {
diff --git a/drivers/media/video/msm/ov7692.c b/drivers/media/video/msm/ov7692.c
index 7372156..7696b44 100644
--- a/drivers/media/video/msm/ov7692.c
+++ b/drivers/media/video/msm/ov7692.c
@@ -522,6 +522,8 @@
 	case CFG_PWR_DOWN:
 		rc = ov7692_power_down();
 		break;
+	case CFG_SET_EFFECT:
+		break;
 	default:
 		rc = -EFAULT;
 		break;
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 1112be7..d882e52 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -214,59 +214,6 @@
 	return rc;
 }
 
-int32_t msm_sensor_setting2(struct msm_sensor_ctrl_t *s_ctrl,
-			int update_type, int res)
-{
-	int32_t rc = 0;
-	static int csi_config;
-
-	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
-	if (csi_config == 0 || res == 0)
-		msleep(66);
-	else
-		msleep(266);
-	if (update_type == MSM_SENSOR_REG_INIT) {
-		CDBG("Register INIT\n");
-		s_ctrl->curr_csi_params = NULL;
-		msm_camera_i2c_write(
-				s_ctrl->sensor_i2c_client,
-				0x103, 0x1,
-				MSM_CAMERA_I2C_BYTE_DATA);
-		msm_sensor_enable_debugfs(s_ctrl);
-		msm_sensor_write_init_settings(s_ctrl);
-		csi_config = 0;
-	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
-		CDBG("PERIODIC : %d\n", res);
-		msm_sensor_write_conf_array(
-			s_ctrl->sensor_i2c_client,
-			s_ctrl->msm_sensor_reg->mode_settings, res);
-		msleep(30);
-		if (!csi_config) {
-			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
-			CDBG("CSI config in progress\n");
-			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
-				NOTIFY_CSIC_CFG,
-				s_ctrl->curr_csic_params);
-			CDBG("CSI config is done\n");
-			mb();
-			msleep(30);
-			csi_config = 1;
-		msm_camera_i2c_write(
-			s_ctrl->sensor_i2c_client,
-			0x100, 0x1,
-			MSM_CAMERA_I2C_BYTE_DATA);
-		}
-		msm_camera_i2c_write(
-			s_ctrl->sensor_i2c_client,
-			0x4800, 0x4,
-			MSM_CAMERA_I2C_BYTE_DATA);
-		msleep(266);
-		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
-		msleep(50);
-	}
-	return rc;
-}
-
 int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
 			int update_type, int res)
 {
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index fed514c..9a85836 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -12,6 +12,7 @@
  */
 
 #include "msm_sensor.h"
+#include "msm.h"
 #define SENSOR_NAME "ov5647"
 #define PLATFORM_DRIVER_NAME "msm_camera_ov5647"
 #define ov5647_obj ov5647_##obj
@@ -333,27 +334,31 @@
 		, gain, line, line);
 
 	if (line > 1964) {
+		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->vert_offset,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines,
 			(uint8_t)((line+4) >> 8),
 			MSM_CAMERA_I2C_BYTE_DATA);
 
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->vert_offset + 1,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
 			(uint8_t)((line+4) & 0x00FF),
 			MSM_CAMERA_I2C_BYTE_DATA);
+		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
 
 		max_line = line + 4;
 	} else if (line > 1968) {
+		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->vert_offset,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines,
 			(uint8_t)((line+4) >> 8),
 			MSM_CAMERA_I2C_BYTE_DATA);
 
 		 msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-			s_ctrl->sensor_exp_gain_info->vert_offset + 1,
+			s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
 			(uint8_t)((line+4) & 0x00FF),
 			MSM_CAMERA_I2C_BYTE_DATA);
+		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
 			max_line = 1968;
 	}
 
@@ -447,24 +452,24 @@
 	if (line > 980) {
 
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->vert_offset,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines,
 		(uint8_t)((line+4) >> 8),
 		MSM_CAMERA_I2C_BYTE_DATA);
 
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->vert_offset + 1,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
 		(uint8_t)((line+4) & 0x00FF),
 		MSM_CAMERA_I2C_BYTE_DATA);
 		max_line = line + 4;
 	} else if (line > 984) {
 
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->vert_offset,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines,
 		(uint8_t)(984 >> 8),
 		MSM_CAMERA_I2C_BYTE_DATA);
 
 		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
-		s_ctrl->sensor_exp_gain_info->vert_offset + 1 ,
+		s_ctrl->sensor_output_reg_addr->frame_length_lines + 1 ,
 		(uint8_t)(984 & 0x00FF),
 		MSM_CAMERA_I2C_BYTE_DATA);
 		max_line = 984;
@@ -568,33 +573,118 @@
 	.video  = &ov5647_subdev_video_ops,
 };
 
+int32_t ov5647_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+{
+	struct msm_camera_sensor_info *info = NULL;
+	unsigned short rdata;
+	int rc;
+
+	info = s_ctrl->sensordata;
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x4202, 0xf,
+		MSM_CAMERA_I2C_BYTE_DATA);
+	msleep(20);
+	rc = msm_camera_i2c_read(s_ctrl->sensor_i2c_client, 0x3018,
+			&rdata, MSM_CAMERA_I2C_WORD_DATA);
+	CDBG("ov5647_sensor_power_down: %d\n", rc);
+	rdata |= 0x18;
+	msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+		0x3018, rdata,
+		MSM_CAMERA_I2C_WORD_DATA);
+	msleep(20);
+	gpio_direction_output(info->sensor_pwd, 1);
+	usleep_range(5000, 5100);
+	msm_sensor_power_down(s_ctrl);
+	return 0;
+}
+
 int32_t ov5647_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
 {
 	int32_t rc = 0;
 	struct msm_camera_sensor_info *info = NULL;
 
+	info = s_ctrl->sensordata;
+	gpio_direction_output(info->sensor_pwd, 1);
+	gpio_direction_output(info->sensor_reset, 0);
+	usleep_range(10000, 11000);
+	if (info->pmic_gpio_enable) {
+		info->pmic_gpio_enable = 0;
+		lcd_camera_power_onoff(1);
+	}
+	usleep_range(10000, 11000);
 	rc = msm_sensor_power_up(s_ctrl);
 	if (rc < 0) {
 		CDBG("%s: msm_sensor_power_up failed\n", __func__);
 		return rc;
 	}
-	info = s_ctrl->sensordata;
 
-	gpio_direction_output(info->sensor_pwd, 1);
-	gpio_direction_output(info->sensor_reset, 0);
-	usleep_range(1000, 1100);
 	/* turn on ldo and vreg */
-	if (info->pmic_gpio_enable)
-		lcd_camera_power_onoff(1);
 
 	gpio_direction_output(info->sensor_pwd, 0);
-	usleep_range(4000, 4100);
+	msleep(20);
 	gpio_direction_output(info->sensor_reset, 1);
-	usleep_range(2000, 2100);
+	msleep(25);
 
 	return rc;
 
 }
+
+int32_t ov5647_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+			int update_type, int res)
+{
+	int32_t rc = 0;
+	static int csi_config;
+
+	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+	if (csi_config == 0 || res == 0)
+		msleep(66);
+	else
+		msleep(266);
+	msm_camera_i2c_write(
+			s_ctrl->sensor_i2c_client,
+			0x4800, 0x25,
+			MSM_CAMERA_I2C_BYTE_DATA);
+	if (update_type == MSM_SENSOR_REG_INIT) {
+		CDBG("Register INIT\n");
+		s_ctrl->curr_csi_params = NULL;
+		msm_camera_i2c_write(
+				s_ctrl->sensor_i2c_client,
+				0x103, 0x1,
+				MSM_CAMERA_I2C_BYTE_DATA);
+		msm_sensor_enable_debugfs(s_ctrl);
+		msm_sensor_write_init_settings(s_ctrl);
+		csi_config = 0;
+	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
+		CDBG("PERIODIC : %d\n", res);
+		msm_sensor_write_conf_array(
+			s_ctrl->sensor_i2c_client,
+			s_ctrl->msm_sensor_reg->mode_settings, res);
+		msleep(30);
+		if (!csi_config) {
+			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
+			CDBG("CSI config in progress\n");
+			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+				NOTIFY_CSIC_CFG,
+				s_ctrl->curr_csic_params);
+			CDBG("CSI config is done\n");
+			mb();
+			msleep(30);
+			csi_config = 1;
+		msm_camera_i2c_write(
+			s_ctrl->sensor_i2c_client,
+			0x100, 0x1,
+			MSM_CAMERA_I2C_BYTE_DATA);
+		}
+		msm_camera_i2c_write(
+			s_ctrl->sensor_i2c_client,
+			0x4800, 0x4,
+			MSM_CAMERA_I2C_BYTE_DATA);
+		msleep(266);
+		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
+		msleep(50);
+	}
+	return rc;
+}
 static struct msm_sensor_fn_t ov5647_func_tbl = {
 	.sensor_start_stream = msm_sensor_start_stream,
 	.sensor_stop_stream = msm_sensor_stop_stream,
@@ -603,13 +693,13 @@
 	.sensor_set_fps = msm_sensor_set_fps,
 	.sensor_write_exp_gain = ov5647_write_prev_exp_gain,
 	.sensor_write_snapshot_exp_gain = ov5647_write_pict_exp_gain,
-	.sensor_setting = msm_sensor_setting2,
+	.sensor_setting = ov5647_sensor_setting,
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
 	.sensor_config = msm_sensor_config,
 	.sensor_power_up = ov5647_sensor_power_up,
-	.sensor_power_down = msm_sensor_power_down,
+	.sensor_power_down = ov5647_sensor_power_down,
 };
 
 static struct msm_sensor_reg_t ov5647_regs = {
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
index 05fe2bb..f296079 100644
--- a/drivers/media/video/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -35,7 +35,9 @@
 #include "vsg-subdev.h"
 
 #define WFD_VERSION KERNEL_VERSION(0, 0, 1)
-#define WFD_DEVICE_NUMBER 38
+#define WFD_NUM_DEVICES 2
+#define WFD_DEVICE_NUMBER_BASE 38
+#define WFD_DEVICE_SECURE (WFD_DEVICE_NUMBER_BASE + 1)
 #define DEFAULT_WFD_WIDTH 640
 #define DEFAULT_WFD_HEIGHT 480
 #define VSG_SCRATCH_BUFFERS 1
@@ -50,6 +52,7 @@
 	struct v4l2_subdev enc_sdev;
 	struct v4l2_subdev vsg_sdev;
 	struct ion_client *ion_client;
+	bool secure_device;
 };
 
 struct mem_info {
@@ -141,17 +144,19 @@
 }
 
 static int wfd_allocate_ion_buffer(struct ion_client *client,
-		struct mem_region *mregion)
+		bool secure, struct mem_region *mregion)
 {
 	struct ion_handle *handle;
 	void *kvaddr, *phys_addr;
 	unsigned long size;
+	unsigned int alloc_regions = 0;
 	int rc;
 
+	alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID);
+	alloc_regions |= secure ? 0 :
+				ION_HEAP(ION_IOMMU_HEAP_ID);
 	handle = ion_alloc(client,
-			mregion->size, SZ_4K,
-			ION_HEAP(ION_IOMMU_HEAP_ID) |
-			ION_HEAP(ION_CP_MM_HEAP_ID));
+			mregion->size, SZ_4K, alloc_regions);
 
 	if (IS_ERR_OR_NULL(handle)) {
 		WFD_MSG_ERR("Failed to allocate input buffer\n");
@@ -256,7 +261,8 @@
 		mdp_mregion = kzalloc(sizeof(*enc_mregion), GFP_KERNEL);
 		enc_mregion->size = ALIGN(inst->input_buf_size, SZ_4K);
 
-		rc = wfd_allocate_ion_buffer(wfd_dev->ion_client, enc_mregion);
+		rc = wfd_allocate_ion_buffer(wfd_dev->ion_client,
+				wfd_dev->secure_device, enc_mregion);
 		if (rc) {
 			WFD_MSG_ERR("Failed to allocate input memory."
 				" This error causes memory leak!!!\n");
@@ -1320,19 +1326,11 @@
 {
 
 }
-static int __devinit __wfd_probe(struct platform_device *pdev)
+
+static int wfd_dev_setup(struct wfd_device *wfd_dev, int dev_num,
+		struct platform_device *pdev)
 {
 	int rc = 0;
-	struct wfd_device *wfd_dev;
-	WFD_MSG_DBG("__wfd_probe: E\n");
-	wfd_dev = kzalloc(sizeof(*wfd_dev), GFP_KERNEL);
-	if (!wfd_dev) {
-		WFD_MSG_ERR("Could not allocate memory for "
-				"wfd device\n");
-		rc = -ENOMEM;
-		goto err_v4l2_registration;
-	}
-	pdev->dev.platform_data = (void *) wfd_dev;
 	rc = v4l2_device_register(&pdev->dev, &wfd_dev->v4l2_dev);
 	if (rc) {
 		WFD_MSG_ERR("Failed to register the video device\n");
@@ -1349,7 +1347,7 @@
 	wfd_dev->pvdev->ioctl_ops = &g_wfd_ioctl_ops;
 
 	rc = video_register_device(wfd_dev->pvdev, VFL_TYPE_GRABBER,
-			WFD_DEVICE_NUMBER);
+			dev_num);
 	if (rc) {
 		WFD_MSG_ERR("Failed to register the device\n");
 		goto err_video_register_device;
@@ -1359,7 +1357,7 @@
 	v4l2_subdev_init(&wfd_dev->mdp_sdev, &mdp_subdev_ops);
 	strncpy(wfd_dev->mdp_sdev.name, "wfd-mdp", V4L2_SUBDEV_NAME_SIZE);
 	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
-						&wfd_dev->mdp_sdev);
+			&wfd_dev->mdp_sdev);
 	if (rc) {
 		WFD_MSG_ERR("Failed to register mdp subdevice: %d\n", rc);
 		goto err_mdp_register_subdev;
@@ -1368,7 +1366,7 @@
 	v4l2_subdev_init(&wfd_dev->enc_sdev, &enc_subdev_ops);
 	strncpy(wfd_dev->enc_sdev.name, "wfd-venc", V4L2_SUBDEV_NAME_SIZE);
 	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
-						&wfd_dev->enc_sdev);
+			&wfd_dev->enc_sdev);
 	if (rc) {
 		WFD_MSG_ERR("Failed to register encoder subdevice: %d\n", rc);
 		goto err_venc_register_subdev;
@@ -1382,23 +1380,14 @@
 	v4l2_subdev_init(&wfd_dev->vsg_sdev, &vsg_subdev_ops);
 	strncpy(wfd_dev->vsg_sdev.name, "wfd-vsg", V4L2_SUBDEV_NAME_SIZE);
 	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
-						&wfd_dev->vsg_sdev);
+			&wfd_dev->vsg_sdev);
 	if (rc) {
 		WFD_MSG_ERR("Failed to register vsg subdevice: %d\n", rc);
 		goto err_venc_init;
 	}
 
-	wfd_dev->ion_client = msm_ion_client_create(-1, "wfd");
-	if (!wfd_dev->ion_client) {
-		WFD_MSG_ERR("Failed to create ion client\n");
-		rc = -ENODEV;
-		goto err_vsg_register_subdev;
-	}
-	WFD_MSG_DBG("__wfd_probe: X\n");
 	return rc;
 
-err_vsg_register_subdev:
-	v4l2_device_unregister_subdev(&wfd_dev->vsg_sdev);
 err_venc_init:
 	v4l2_device_unregister_subdev(&wfd_dev->enc_sdev);
 err_venc_register_subdev:
@@ -1410,6 +1399,66 @@
 err_video_device_alloc:
 	v4l2_device_unregister(&wfd_dev->v4l2_dev);
 err_v4l2_registration:
+	return rc;
+}
+static int __devinit __wfd_probe(struct platform_device *pdev)
+{
+	int rc = 0, c = 0;
+	struct wfd_device *wfd_dev; /* Should be taken as an array*/
+	struct ion_client *ion_client = NULL;
+
+	WFD_MSG_DBG("__wfd_probe: E\n");
+	wfd_dev = kzalloc(sizeof(*wfd_dev)*WFD_NUM_DEVICES, GFP_KERNEL);
+	if (!wfd_dev) {
+		WFD_MSG_ERR("Could not allocate memory for "
+				"wfd device\n");
+		rc = -ENOMEM;
+		goto err_v4l2_probe;
+	}
+	pdev->dev.platform_data = (void *) wfd_dev;
+
+	ion_client = msm_ion_client_create(-1, "wfd");
+	if (!ion_client) {
+		WFD_MSG_ERR("Failed to create ion client\n");
+		rc = -ENODEV;
+		goto err_v4l2_probe;
+	}
+
+	for (c = 0; c < WFD_NUM_DEVICES; ++c) {
+		rc = wfd_dev_setup(&wfd_dev[c],
+			WFD_DEVICE_NUMBER_BASE + c, pdev);
+
+		if (rc) {
+			/* Clear out old devices */
+			for (--c; c >= 0; --c) {
+				v4l2_device_unregister_subdev(
+						&wfd_dev[c].vsg_sdev);
+				v4l2_device_unregister_subdev(
+						&wfd_dev[c].enc_sdev);
+				v4l2_device_unregister_subdev(
+						&wfd_dev[c].mdp_sdev);
+				video_unregister_device(wfd_dev[c].pvdev);
+				video_device_release(wfd_dev[c].pvdev);
+				v4l2_device_unregister(&wfd_dev[c].v4l2_dev);
+			}
+
+			goto err_v4l2_probe;
+		}
+
+		/* Other device specific stuff */
+		wfd_dev[c].ion_client = ion_client;
+		switch (WFD_DEVICE_NUMBER_BASE + c) {
+		case WFD_DEVICE_SECURE:
+			wfd_dev[c].secure_device = true;
+			break;
+		default:
+			break;
+		}
+
+	}
+	WFD_MSG_DBG("__wfd_probe: X\n");
+	return rc;
+err_v4l2_probe:
 	kfree(wfd_dev);
 	return rc;
 }
@@ -1417,6 +1466,8 @@
 static int __devexit __wfd_remove(struct platform_device *pdev)
 {
 	struct wfd_device *wfd_dev;
+	int c = 0;
+
 	wfd_dev = (struct wfd_device *)pdev->dev.platform_data;
 
 	WFD_MSG_DBG("Inside wfd_remove\n");
@@ -1425,10 +1476,15 @@
 		return -ENODEV;
 	}
 
-	v4l2_device_unregister_subdev(&wfd_dev->mdp_sdev);
-	video_unregister_device(wfd_dev->pvdev);
-	video_device_release(wfd_dev->pvdev);
-	v4l2_device_unregister(&wfd_dev->v4l2_dev);
+	for (c = 0; c < WFD_NUM_DEVICES; ++c) {
+		v4l2_device_unregister_subdev(&wfd_dev[c].vsg_sdev);
+		v4l2_device_unregister_subdev(&wfd_dev[c].enc_sdev);
+		v4l2_device_unregister_subdev(&wfd_dev[c].mdp_sdev);
+		video_unregister_device(wfd_dev[c].pvdev);
+		video_device_release(wfd_dev[c].pvdev);
+		v4l2_device_unregister(&wfd_dev[c].v4l2_dev);
+	}
+
 	kfree(wfd_dev);
 	return 0;
 }
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index c12bed3..7782955 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -45,9 +45,9 @@
 #define D(fmt, args...) do {} while (0)
 #endif
 
-static int32_t msm_mem_allocate(struct videobuf2_contig_pmem *mem)
+static unsigned long msm_mem_allocate(struct videobuf2_contig_pmem *mem)
 {
-	int32_t phyaddr;
+	unsigned long phyaddr;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	int rc, len;
 	mem->client = msm_ion_client_create(-1, "camera");
@@ -61,8 +61,10 @@
 		pr_err("%s Could not allocate\n", __func__);
 		goto alloc_failed;
 	}
-	rc = ion_phys(mem->client, mem->ion_handle, (ion_phys_addr_t *)&phyaddr,
-		 (size_t *)&len);
+	rc = ion_map_iommu(mem->client, mem->ion_handle,
+			CAMERA_DOMAIN, GEN_POOL, SZ_4K, 0,
+			(unsigned long *)&phyaddr,
+			(unsigned long *)&len, UNCACHED, 0);
 	if (rc < 0) {
 		pr_err("%s Could not get physical address\n", __func__);
 		goto phys_failed;
@@ -85,6 +87,7 @@
 {
 	int32_t rc = 0;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_unmap_iommu(mem->client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL);
 	ion_free(mem->client, mem->ion_handle);
 	ion_client_destroy(mem->client);
 #else
@@ -116,8 +119,6 @@
 static void *msm_vb2_mem_ops_alloc(void *alloc_ctx, unsigned long size)
 {
 	struct videobuf2_contig_pmem *mem;
-	unsigned int flags = 0;
-	long rc;
 	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
 	if (!mem)
 		return ERR_PTR(-ENOMEM);
@@ -132,18 +133,7 @@
 		kfree(mem);
 		return ERR_PTR(-ENOMEM);
 	}
-	flags = MSM_SUBSYSTEM_MAP_IOVA;
-	mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
-	mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, mem->size,
-					flags, &(mem->subsys_id), 1);
-	if (IS_ERR((void *)mem->msm_buffer)) {
-		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
-		rc = PTR_ERR((void *)mem->msm_buffer);
-		msm_mem_free(mem);
-		kfree(mem);
-		return ERR_PTR(-ENOMEM);
-	}
-	mem->mapped_phyaddr = mem->msm_buffer->iova[0];
+	mem->mapped_phyaddr = mem->phyaddr;
 	return mem;
 }
 static void msm_vb2_mem_ops_put(void *buf_priv)
@@ -151,8 +141,6 @@
 	struct videobuf2_contig_pmem *mem = buf_priv;
 	if (!mem->is_userptr) {
 		D("%s Freeing memory ", __func__);
-		if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
-			D("%s unmapped memory\n", __func__);
 		msm_mem_free(mem);
 	}
 	kfree(mem);
@@ -193,7 +181,6 @@
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned long kvstart;
 #endif
-	unsigned int flags = 0;
 	unsigned long paddr = 0;
 	if (mem->phyaddr != 0)
 		return 0;
@@ -203,8 +190,10 @@
 		pr_err("%s ION import failed\n", __func__);
 		return PTR_ERR(mem->ion_handle);
 	}
-	rc = ion_phys(client, mem->ion_handle, (ion_phys_addr_t *)&mem->phyaddr,
-			 (size_t *)&len);
+	rc = ion_map_iommu(client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL,
+		SZ_4K, 0, (unsigned long *)&mem->phyaddr, &len, UNCACHED, 0);
+	if (rc < 0)
+		ion_free(client, mem->ion_handle);
 #elif CONFIG_ANDROID_PMEM
 	rc = get_pmem_file((int)mem->vaddr, (unsigned long *)&mem->phyaddr,
 					&kvstart, &len, &mem->file);
@@ -224,20 +213,6 @@
 	mem->path = path;
 	mem->buffer_type = buffer_type;
 	paddr = mem->phyaddr;
-	flags = MSM_SUBSYSTEM_MAP_IOVA;
-	mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
-	mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, len,
-					flags, &(mem->subsys_id), 1);
-	if (IS_ERR((void *)mem->msm_buffer)) {
-		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		ion_free(client, mem->ion_handle);
-#elif CONFIG_ANDROID_PMEM
-		put_pmem_file(mem->file);
-#endif
-		return PTR_ERR((void *)mem->msm_buffer);
-	}
-	paddr = mem->msm_buffer->iova[0];
 	mem->mapped_phyaddr = paddr + addr_offset;
 	mem->addr_offset = addr_offset;
 	return rc;
@@ -247,10 +222,10 @@
 void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem,
 					struct ion_client *client)
 {
-	if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
-		D("%s unmapped memory\n", __func__);
 	if (mem->is_userptr) {
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_unmap_iommu(client, mem->ion_handle,
+				CAMERA_DOMAIN, GEN_POOL);
 		ion_free(client, mem->ion_handle);
 #elif CONFIG_ANDROID_PMEM
 		put_pmem_file(mem->file);
diff --git a/drivers/mfd/pm8018-core.c b/drivers/mfd/pm8018-core.c
index f986b5d..041815776 100644
--- a/drivers/mfd/pm8018-core.c
+++ b/drivers/mfd/pm8018-core.c
@@ -284,7 +284,7 @@
 #define MAX_NAME_COMPARISON_LEN 32
 
 static int __devinit match_regulator(
-	struct pm8xxx_regulator_core_platform_data *core_data, char *name)
+	struct pm8xxx_regulator_core_platform_data *core_data, const char *name)
 {
 	int found = 0;
 	int i;
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index ac57418..b03b7ac 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.c
@@ -326,7 +326,7 @@
 #define MAX_NAME_COMPARISON_LEN 32
 
 static int __devinit match_regulator(
-	struct pm8xxx_regulator_core_platform_data *core_data, char *name)
+	struct pm8xxx_regulator_core_platform_data *core_data, const char *name)
 {
 	int found = 0;
 	int i;
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 68395e3..0f41ba7 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -448,7 +448,7 @@
 #define MAX_NAME_COMPARISON_LEN 32
 
 static int __devinit match_regulator(enum pm8xxx_version version,
-	struct pm8xxx_regulator_core_platform_data *core_data, char *name)
+	struct pm8xxx_regulator_core_platform_data *core_data, const char *name)
 {
 	int found = 0;
 	int i;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index ba00d5e..26a69f1 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1,3 +1,4 @@
+
 /* Qualcomm Secure Execution Environment Communicator (QSEECOM) driver
  *
  * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
@@ -552,7 +553,8 @@
 		}
 
 		if (data->abort) {
-			pr_err("Aborting driver\n");
+			pr_err("Aborting listener service %d\n",
+				data->listener.id);
 			return -ENODEV;
 		}
 		qseecom.send_resp_flag = 0;
@@ -605,7 +607,8 @@
 		app_id = resp.data;
 
 	if (app_id) {
-		pr_warn("App id already exists\n");
+		pr_warn("App id %d (%s) already exists\n", app_id,
+			(char *)(req.app_name));
 		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
 		list_for_each_entry(entry,
 				&qseecom.registered_app_list_head, list){
@@ -619,7 +622,8 @@
 	} else {
 		struct qseecom_load_app_ireq load_req;
 
-		pr_warn("App id does not exist\n");
+		pr_warn("App (%s) does not exist, loading apps for first time\n",
+			(char *)(load_req.app_name));
 		/* Get the handle of the shared fd */
 		ihandle = ion_import_fd(qseecom.ion_clnt,
 					load_img_req.ifd_data_fd);
@@ -642,6 +646,13 @@
 				sizeof(struct qseecom_load_app_ireq),
 				&resp, sizeof(resp));
 
+		if (resp.result == QSEOS_RESULT_FAILURE) {
+			pr_err("scm_call failed resp.result QSEOS_RESULT_FAILURE -1\n");
+			if (!IS_ERR_OR_NULL(ihandle))
+				ion_free(qseecom.ion_clnt, ihandle);
+			return -EFAULT;
+		}
+
 		if (resp.result == QSEOS_RESULT_INCOMPLETE) {
 			ret = __qseecom_process_incomplete_cmd(data, &resp);
 			if (ret) {
@@ -653,7 +664,8 @@
 			}
 		}
 		if (resp.result != QSEOS_RESULT_SUCCESS) {
-			pr_err("scm_call failed resp.result != QSEOS_RESULT_SUCCESS\n");
+			pr_err("scm_call failed resp.result unknown, %d\n",
+					resp.result);
 			if (!IS_ERR_OR_NULL(ihandle))
 				ion_free(qseecom.ion_clnt, ihandle);
 			return -EFAULT;
@@ -677,6 +689,9 @@
 		list_add_tail(&entry->list, &qseecom.registered_app_list_head);
 		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
 					flags);
+
+		pr_warn("App with id %d  (%s) now loaded\n", app_id,
+			(char *)(load_req.app_name));
 	}
 	data->client.app_id = app_id;
 	load_img_req.app_id = app_id;
@@ -720,10 +735,14 @@
 					unload = __qseecom_cleanup_app(data);
 					list_del(&ptr_app->list);
 					kzfree(ptr_app);
+					pr_warn("App id %d now unloaded\n",
+							ptr_app->app_id);
 					break;
 				} else {
 					ptr_app->ref_cnt--;
 					data->released = true;
+					pr_warn("Can't unload app with id %d (it is inuse)\n",
+							ptr_app->app_id);
 					break;
 				}
 			}
@@ -748,7 +767,7 @@
 				sizeof(struct qseecom_unload_app_ireq),
 				&resp, sizeof(resp));
 		if (ret) {
-			pr_err("Fail to unload APP\n");
+			pr_err("Fail to unload app id %d\n", req.app_id);
 			return -EFAULT;
 		}
 		if (resp.result == QSEOS_RESULT_INCOMPLETE) {
@@ -964,7 +983,7 @@
 	int i = 0;
 
 	for (i = 0; i < MAX_ION_FD; i++) {
-		if (req->ifd_data[i].fd != 0) {
+		if (req->ifd_data[i].fd > 0) {
 			field = (char *)req->cmd_req_buf +
 					req->ifd_data[i].cmd_buf_offset;
 			update = (uint32_t *) field;
@@ -986,7 +1005,7 @@
 	uint32_t length;
 
 	for (i = 0; i < MAX_ION_FD; i++) {
-		if (req->ifd_data[i].fd != 0) {
+		if (req->ifd_data[i].fd > 0) {
 			/* Get the handle of the shared fd */
 			ihandle = ion_import_fd(qseecom.ion_clnt,
 						req->ifd_data[i].fd);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index ce2176e..9385087 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -626,6 +626,11 @@
 		else if (host->ios.clock <= 200000000)
 			index = EXT_CSD_PWR_CL_200_195;
 		break;
+	case MMC_VDD_27_28:
+	case MMC_VDD_28_29:
+	case MMC_VDD_29_30:
+	case MMC_VDD_30_31:
+	case MMC_VDD_31_32:
 	case MMC_VDD_32_33:
 	case MMC_VDD_33_34:
 	case MMC_VDD_34_35:
@@ -1036,11 +1041,10 @@
 		ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
 				EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
 		err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
-		if (err) {
-			pr_err("%s: power class selection to bus width %d failed\n",
-				mmc_hostname(card->host), 1 << bus_width);
-			goto err;
-		}
+		if (err)
+			pr_warning("%s: power class selection to bus width %d"
+				   " failed\n", mmc_hostname(card->host),
+				   1 << bus_width);
 	}
 
 	/*
@@ -1072,10 +1076,10 @@
 			err = mmc_select_powerclass(card, ext_csd_bits[idx][0],
 						    ext_csd);
 			if (err)
-				pr_err("%s: power class selection to "
-				       "bus width %d failed\n",
-				       mmc_hostname(card->host),
-				       1 << bus_width);
+				pr_warning("%s: power class selection to "
+					   "bus width %d failed\n",
+					   mmc_hostname(card->host),
+					   1 << bus_width);
 
 			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 					 EXT_CSD_BUS_WIDTH,
@@ -1103,10 +1107,10 @@
 			err = mmc_select_powerclass(card, ext_csd_bits[idx][1],
 						    ext_csd);
 			if (err)
-				pr_err("%s: power class selection to "
-				       "bus width %d ddr %d failed\n",
-				       mmc_hostname(card->host),
-				       1 << bus_width, ddr);
+				pr_warning("%s: power class selection to "
+					   "bus width %d ddr %d failed\n",
+					   mmc_hostname(card->host),
+					   1 << bus_width, ddr);
 
 			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 					 EXT_CSD_BUS_WIDTH,
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index 8b250c12..28505636 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -31,17 +31,6 @@
 {
 	int i, ret, count;
 	unsigned char pending;
-	struct sdio_func *func;
-
-	/*
-	 * Optimization, if there is only 1 function interrupt registered
-	 * call irq handler directly
-	 */
-	func = card->sdio_single_irq;
-	if (func) {
-		func->irq_handler(func);
-		return 1;
-	}
 
 	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
 	if (ret) {
@@ -53,7 +42,7 @@
 	count = 0;
 	for (i = 1; i <= 7; i++) {
 		if (pending & (1 << i)) {
-			func = card->sdio_func[i - 1];
+			struct sdio_func *func = card->sdio_func[i - 1];
 			if (!func) {
 				printk(KERN_WARNING "%s: pending IRQ for "
 					"non-existent function\n",
@@ -203,24 +192,6 @@
 	return 0;
 }
 
-/* If there is only 1 function registered set sdio_single_irq */
-static void sdio_single_irq_set(struct mmc_card *card)
-{
-	struct sdio_func *func;
-	int i;
-
-	card->sdio_single_irq = NULL;
-	if ((card->host->caps & MMC_CAP_SDIO_IRQ) &&
-	    card->host->sdio_irqs == 1)
-		for (i = 0; i < card->sdio_funcs; i++) {
-		       func = card->sdio_func[i];
-		       if (func && func->irq_handler) {
-			       card->sdio_single_irq = func;
-			       break;
-		       }
-	       }
-}
-
 /**
  *	sdio_claim_irq - claim the IRQ for a SDIO function
  *	@func: SDIO function
@@ -262,7 +233,6 @@
 	ret = sdio_card_irq_get(func->card);
 	if (ret)
 		func->irq_handler = NULL;
-	sdio_single_irq_set(func->card);
 
 	return ret;
 }
@@ -287,7 +257,6 @@
 	if (func->irq_handler) {
 		func->irq_handler = NULL;
 		sdio_card_irq_put(func->card);
-		sdio_single_irq_set(func->card);
 	}
 
 	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 69ec647..f03aeac 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3201,14 +3201,15 @@
 static int find_most_appropriate_phase(struct msmsdcc_host *host,
 				u8 *phase_table, u8 total_phases)
 {
+	#define MAX_PHASES 16
 	int ret;
-	u8 ranges[16][16] = { {0}, {0} };
-	u8 phases_per_row[16] = {0};
+	u8 ranges[MAX_PHASES][MAX_PHASES] = { {0}, {0} };
+	u8 phases_per_row[MAX_PHASES] = {0};
 	int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0;
 	int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0;
 	bool phase_0_found = false, phase_15_found = false;
 
-	if (total_phases > 16) {
+	if (!total_phases || (total_phases > MAX_PHASES)) {
 		pr_err("%s: %s: invalid argument: total_phases=%d\n",
 			mmc_hostname(host->mmc), __func__, total_phases);
 		return -EINVAL;
@@ -3228,6 +3229,9 @@
 		}
 	}
 
+	if (row_index >= MAX_PHASES)
+		return -EINVAL;
+
 	/* Check if phase-0 is present in first valid window? */
 	if (!ranges[0][0]) {
 		phase_0_found = true;
@@ -3235,7 +3239,7 @@
 		/* Check if cycle exist between 2 valid windows */
 		for (cnt = 1; cnt <= row_index; cnt++) {
 			if (phases_per_row[cnt]) {
-				for (i = 0; i <= phases_per_row[cnt]; i++) {
+				for (i = 0; i < phases_per_row[cnt]; i++) {
 					if (ranges[cnt][i] == 15) {
 						phase_15_found = true;
 						phase_15_raw_index = cnt;
@@ -3253,12 +3257,23 @@
 		/* number of phases in raw where phase 15 is present */
 		u8 phases_15 = phases_per_row[phase_15_raw_index];
 
-		cnt = 0;
-		for (i = phases_15; i < (phases_15 + phases_0); i++) {
+		if (phases_0 + phases_15 >= MAX_PHASES)
+			/*
+			 * If there are more than 1 phase windows then total
+			 * number of phases in both the windows should not be
+			 * more than or equal to MAX_PHASES.
+			 */
+			return -EINVAL;
+
+		/* Merge 2 cyclic windows */
+		i = phases_15;
+		for (cnt = 0; cnt < phases_0; cnt++) {
 			ranges[phase_15_raw_index][i] =
 				ranges[phase_0_raw_index][cnt];
-			cnt++;
+			if (++i >= MAX_PHASES)
+				break;
 		}
+
 		phases_per_row[phase_0_raw_index] = 0;
 		phases_per_row[phase_15_raw_index] = phases_15 + phases_0;
 	}
@@ -3270,9 +3285,18 @@
 		}
 	}
 
-	i = ((curr_max * 3) / 4) - 1;
+	i = ((curr_max * 3) / 4);
+	if (i)
+		i--;
+
 	ret = (int)ranges[selected_row_index][i];
 
+	if (ret >= MAX_PHASES) {
+		ret = -EINVAL;
+		pr_err("%s: %s: invalid phase selected=%d\n",
+			mmc_hostname(host->mmc), __func__, ret);
+	}
+
 	return ret;
 }
 
diff --git a/drivers/net/wireless/libra/libra_sdioif.c b/drivers/net/wireless/libra/libra_sdioif.c
index 9b90184..8cfc0fa 100644
--- a/drivers/net/wireless/libra/libra_sdioif.c
+++ b/drivers/net/wireless/libra/libra_sdioif.c
@@ -29,6 +29,7 @@
 static suspend_handler_t *libra_suspend_hldr;
 static resume_handler_t *libra_resume_hldr;
 static notify_card_removal_t *libra_notify_card_removal_hdlr;
+static shutdown_handler_t *libra_sdio_shutdown_hdlr;
 
 int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable)
 {
@@ -452,6 +453,23 @@
 #define libra_sdio_resume 0
 #endif
 
+static void libra_sdio_shutdown(struct device *dev)
+{
+	if (libra_sdio_shutdown_hdlr) {
+		libra_sdio_shutdown_hdlr();
+		printk(KERN_INFO "%s : Notified shutdown event to Libra driver.\n",
+			 __func__);
+	}
+}
+
+int libra_sdio_register_shutdown_hdlr(
+		shutdown_handler_t *libra_shutdown_hdlr)
+{
+	libra_sdio_shutdown_hdlr = libra_shutdown_hdlr;
+	return 0;
+}
+EXPORT_SYMBOL(libra_sdio_register_shutdown_hdlr);
+
 int libra_sdio_notify_card_removal(
 		notify_card_removal_t *libra_sdio_notify_card_removal_hdlr)
 {
@@ -472,11 +490,12 @@
 };
 
 static struct sdio_driver libra_sdiofn_driver = {
-    .name      = "libra_sdiofn",
-    .id_table  = libra_sdioid,
-    .probe     = libra_sdio_probe,
-    .remove    = libra_sdio_remove,
-    .drv.pm    = &libra_sdio_pm_ops,
+	.name      = "libra_sdiofn",
+	.id_table  = libra_sdioid,
+	.probe     = libra_sdio_probe,
+	.remove    = libra_sdio_remove,
+	.drv.pm    = &libra_sdio_pm_ops,
+	.drv.shutdown    = libra_sdio_shutdown,
 };
 
 static int __init libra_sdioif_init(void)
@@ -487,6 +506,7 @@
 	libra_suspend_hldr = NULL;
 	libra_resume_hldr = NULL;
 	libra_notify_card_removal_hdlr = NULL;
+	libra_sdio_shutdown_hdlr = NULL;
 
 	sdio_register_driver(&libra_sdiofn_driver);
 
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index a306357..b8cdc6b 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -81,4 +81,10 @@
 	help
 	  OpenFirmware SPMI bus accessors
 
+config OF_SLIMBUS
+	def_tristate SLIMBUS
+	depends on SLIMBUS
+	help
+	  OpenFirmware SLIMBUS accessors
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 2087c5e..bc2b481 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -11,3 +11,4 @@
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_SPMI)	+= of_spmi.o
+obj-$(CONFIG_OF_SLIMBUS)	+= of_slimbus.o
diff --git a/drivers/of/of_slimbus.c b/drivers/of/of_slimbus.c
new file mode 100644
index 0000000..512ca73
--- /dev/null
+++ b/drivers/of/of_slimbus.c
@@ -0,0 +1,83 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/* OF helpers for SLIMbus */
+#include <linux/slimbus/slimbus.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_slimbus.h>
+
+int of_register_slim_devices(struct slim_controller *ctrl)
+{
+	struct device_node *node;
+	struct slim_boardinfo *binfo = NULL;
+	int n = 0;
+	int ret = 0;
+
+	if (!ctrl->dev.of_node)
+		return -EINVAL;
+
+	for_each_child_of_node(ctrl->dev.of_node, node) {
+		struct property *prop;
+		struct slim_device *slim;
+		char *name;
+		prop = of_find_property(node, "elemental-addr", NULL);
+		if (!prop || prop->length != 6) {
+			dev_err(&ctrl->dev, "of_slim: invalid E-addr");
+			continue;
+		}
+		name = kzalloc(SLIMBUS_NAME_SIZE, GFP_KERNEL);
+		if (!name) {
+			dev_err(&ctrl->dev, "of_slim: out of memory");
+			ret = -ENOMEM;
+			goto of_slim_err;
+		}
+		if (of_modalias_node(node, name, SLIMBUS_NAME_SIZE) < 0) {
+			dev_err(&ctrl->dev, "of_slim: modalias failure on %s\n",
+				node->full_name);
+			kfree(name);
+			continue;
+		}
+		slim = kzalloc(sizeof(struct slim_device), GFP_KERNEL);
+		if (!slim) {
+			dev_err(&ctrl->dev, "of_slim: out of memory");
+			ret = -ENOMEM;
+			kfree(name);
+			goto of_slim_err;
+		}
+		memcpy(slim->e_addr, prop->value, 6);
+
+		binfo = krealloc(binfo, (n + 1) * sizeof(struct slim_boardinfo),
+					GFP_KERNEL);
+		if (!binfo) {
+			dev_err(&ctrl->dev, "out of memory");
+			kfree(name);
+			kfree(slim);
+			return -ENOMEM;
+		}
+		slim->name = (const char *)name;
+		binfo[n].bus_num = ctrl->nr;
+		binfo[n].slim_slave = slim;
+		n++;
+	}
+	return slim_register_board_info(binfo, n);
+of_slim_err:
+	n--;
+	while (n >= 0) {
+		kfree(binfo[n].slim_slave->name);
+		kfree(binfo[n].slim_slave);
+	}
+	kfree(binfo);
+	return ret;
+}
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index edef402..f2981bf 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -27,7 +27,7 @@
  *
  */
 #define BAM_MIN_VERSION 2
-#define BAM_MAX_VERSION 0x1f
+#define BAM_MAX_VERSION 0x2f
 
 #ifdef CONFIG_SPS_SUPPORT_NDP_BAM
 
@@ -95,6 +95,8 @@
  *
  */
 /* CTRL */
+#define CACHE_MISS_ERR_RESP_EN                 0x80000
+#define LOCAL_CLK_GATING                       0x60000
 #define IBC_DISABLE                            0x10000
 #define BAM_CACHED_DESC_STORE                   0x8000
 #define BAM_DESC_CACHE_SEL                      0x6000
@@ -172,17 +174,23 @@
 #define AHB_MASTER_ERR_CTRLS_BAM_ERR_HTRANS             0x3
 
 /* TRUST_REG  */
+#define LOCK_EE_CTRL                            0x2000
 #define BAM_VMID                                0x1f00
 #define BAM_RST_BLOCK                             0x80
 #define BAM_EE                                     0x7
 
 /* TEST_BUS_SEL */
+#define BAM_SW_EVENTS_ZERO                    0x200000
+#define BAM_SW_EVENTS_SEL                     0x180000
 #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_MULTIPLE_EVENTS_DESC_AVAIL_EN  0x40000000
+#define CNFG_BITS_MULTIPLE_EVENTS_SIZE_EN        0x20000000
+#define CNFG_BITS_BAM_ZLT_W_CD_SUPPORT           0x10000000
 #define CNFG_BITS_BAM_CD_ENABLE                   0x8000000
 #define CNFG_BITS_BAM_AU_ACCUMED                  0x4000000
 #define CNFG_BITS_BAM_PSM_P_HD_DATA               0x2000000
@@ -222,6 +230,7 @@
 
 /* P_TRUST_REGn */
 #define BAM_P_VMID                              0x1f00
+#define BAM_P_SUP_GROUP                           0xf8
 #define BAM_P_EE                                   0x7
 
 /* P_IRQ_STTSn */
@@ -663,6 +672,12 @@
 
 	bam_write_reg_field(base, CTRL, BAM_EN, 1);
 
+#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
+	bam_write_reg_field(base, CTRL, CACHE_MISS_ERR_RESP_EN, 1);
+
+	bam_write_reg_field(base, CTRL, LOCAL_CLK_GATING, 1);
+#endif
+
 	bam_write_reg(base, DESC_CNT_TRSHLD, summing_threshold);
 
 	bam_write_reg(base, CNFG_BITS, cfg_bits);
@@ -862,6 +877,14 @@
 	bam_write_reg_field(base, P_CTRL(pipe), P_SYS_STRM,
 			    param->stream_mode);
 
+#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
+	bam_write_reg_field(base, P_CTRL(pipe), P_LOCK_GROUP,
+				param->lock_group);
+
+	SPS_DBG("sps:bam=0x%x(va).pipe=%d.lock_group=%d.\n",
+			(u32) base, pipe, param->lock_group);
+#endif
+
 	if (param->mode == BAM_PIPE_MODE_BAM2BAM) {
 		u32 peer_dest_addr = param->peer_phys_addr +
 				      P_EVNT_REG(param->peer_pipe);
@@ -878,6 +901,14 @@
 			(u32) base, pipe,
 			(u32) param->peer_phys_addr,
 			param->peer_pipe);
+
+#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
+		bam_write_reg_field(base, P_CTRL(pipe), P_WRITE_NWD,
+					param->write_nwd);
+
+		SPS_DBG("sps:%s WRITE_NWD bit for this bam2bam pipe.",
+			param->write_nwd ? "Set" : "Do not set");
+#endif
 	}
 
 	/* Pipe Enable - at last */
diff --git a/drivers/platform/msm/sps/bam.h b/drivers/platform/msm/sps/bam.h
index d672a88..789769f 100644
--- a/drivers/platform/msm/sps/bam.h
+++ b/drivers/platform/msm/sps/bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,13 @@
 	BAM_STREAM_MODE_ENABLE = 1,
 };
 
+/* NWD written Type */
+enum bam_write_nwd {
+	BAM_WRITE_NWD_DISABLE = 0,
+	BAM_WRITE_NWD_ENABLE = 1,
+};
+
+
 /* Enable Type */
 enum bam_enable {
 	BAM_DISABLE = 0,
@@ -63,8 +70,10 @@
 	u32 pipe_irq_mask;
 	enum bam_pipe_dir dir;
 	enum bam_pipe_mode mode;
+	enum bam_write_nwd write_nwd;
 	u32 desc_base;	/* Physical address of descriptor FIFO */
 	u32 desc_size;	/* Size (bytes) of descriptor FIFO */
+	u32 lock_group;	/* The lock group this pipe belongs to */
 	enum bam_stream_mode stream_mode;
 	u32 ee;		/* BAM execution environment index */
 
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index b876d2d..217f18d 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -824,6 +824,12 @@
 		return -EAGAIN;
 	}
 
+	if ((connect->lock_group != SPSRM_CLEAR)
+		&& (connect->lock_group > BAM_MAX_P_LOCK_GROUP_NUM)) {
+		SPS_ERR("sps:The value of pipe lock group is invalid.\n");
+		return SPS_ERROR;
+	}
+
 	mutex_lock(&sps->lock);
 	/*
 	 * Must lock the BAM device at the top level function, so must
@@ -1060,6 +1066,34 @@
 
 	SPS_DBG("sps:%s.", __func__);
 
+	if ((flags & SPS_IOVEC_FLAG_NWD) &&
+		!(flags & (SPS_IOVEC_FLAG_EOT | SPS_IOVEC_FLAG_CMD))) {
+		SPS_ERR("sps:NWD is only valid with EOT or CMD.\n");
+		return SPS_ERROR;
+	} else if ((flags & SPS_IOVEC_FLAG_EOT) &&
+		(flags & SPS_IOVEC_FLAG_CMD)) {
+		SPS_ERR("sps:EOT and CMD are not allowed to coexist.\n");
+		return SPS_ERROR;
+	} else if (!(flags & SPS_IOVEC_FLAG_CMD) &&
+		(flags & (SPS_IOVEC_FLAG_LOCK | SPS_IOVEC_FLAG_UNLOCK))) {
+		SPS_ERR("sps:pipe lock and unlock flags are only valid with "
+			"Command Descriptor.\n");
+		return SPS_ERROR;
+	} else if ((flags & SPS_IOVEC_FLAG_LOCK) &&
+		(flags & SPS_IOVEC_FLAG_UNLOCK)) {
+		SPS_ERR("sps:Can't lock and unlock a pipe by the same"
+			"Command Descriptor.\n");
+		return SPS_ERROR;
+	} else if ((flags & SPS_IOVEC_FLAG_IMME) &&
+		(flags & SPS_IOVEC_FLAG_CMD)) {
+		SPS_ERR("sps:Immediate and CMD are not allowed to coexist.\n");
+		return SPS_ERROR;
+	} else if ((flags & SPS_IOVEC_FLAG_IMME) &&
+		(flags & SPS_IOVEC_FLAG_NWD)) {
+		SPS_ERR("sps:Immediate and NWD are not allowed to coexist.\n");
+		return SPS_ERROR;
+	}
+
 	bam = sps_bam_lock(pipe);
 	if (bam == NULL)
 		return SPS_ERROR;
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index b5192d1..da1de86 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -35,7 +35,9 @@
 
 /* Mask for valid hardware descriptor flags */
 #define BAM_IOVEC_FLAG_MASK   \
-	(SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT | SPS_IOVEC_FLAG_EOB)
+	(SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT | SPS_IOVEC_FLAG_EOB |   \
+	SPS_IOVEC_FLAG_NWD | SPS_IOVEC_FLAG_CMD | SPS_IOVEC_FLAG_LOCK |   \
+	SPS_IOVEC_FLAG_UNLOCK | SPS_IOVEC_FLAG_IMME)
 
 /* Mask for invalid BAM-to-BAM pipe options */
 #define BAM2BAM_O_INVALID   \
@@ -712,6 +714,7 @@
 	}
 	hw_params.event_threshold = (u16) map_pipe->event_threshold;
 	hw_params.ee = dev->props.ee;
+	hw_params.lock_group = map_pipe->lock_group;
 
 	/* Verify that control of this pipe is allowed */
 	if ((dev->props.manage & SPS_BAM_MGR_PIPE_NO_CTRL) ||
@@ -751,6 +754,14 @@
 		/* Clear the data FIFO for debug */
 		if (map->data.base != NULL && bam_pipe->mode == SPS_MODE_SRC)
 			memset(map->data.base, 0, hw_params.data_size);
+
+		/* set NWD bit for BAM2BAM producer pipe */
+		if (bam_pipe->mode == SPS_MODE_SRC) {
+			if ((params->options & SPS_O_WRITE_NWD) == 0)
+				hw_params.write_nwd = BAM_WRITE_NWD_DISABLE;
+			else
+				hw_params.write_nwd = BAM_WRITE_NWD_ENABLE;
+		}
 	} else {
 		/* System mode */
 		hw_params.mode = BAM_PIPE_MODE_SYSTEM;
diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c
index 75194e0..c980eb0 100644
--- a/drivers/platform/msm/sps/sps_rm.c
+++ b/drivers/platform/msm/sps/sps_rm.c
@@ -22,9 +22,6 @@
 #include "spsi.h"
 #include "sps_core.h"
 
-/* "Clear" value for the connection parameter struct */
-#define SPSRM_CLEAR     0xcccccccc
-
 /* Max BAM FIFO sizes */
 #define SPSRM_MAX_DESC_FIFO_SIZE    0xffff
 #define SPSRM_MAX_DATA_FIFO_SIZE    0xffff
@@ -198,6 +195,8 @@
 		pipe->pipe_index = map->src.pipe_index;
 		if (pipe->connect.event_thresh != SPSRM_CLEAR)
 			map->src.event_threshold = pipe->connect.event_thresh;
+		if (pipe->connect.lock_group != SPSRM_CLEAR)
+			map->src.lock_group = pipe->connect.lock_group;
 	} else {
 		map->client_dest = pipe;
 		pipe->bam = map->dest.bam;
@@ -205,6 +204,8 @@
 		if (pipe->connect.event_thresh != SPSRM_CLEAR)
 			map->dest.event_threshold =
 			pipe->connect.event_thresh;
+		if (pipe->connect.lock_group != SPSRM_CLEAR)
+			map->dest.lock_group = pipe->connect.lock_group;
 	}
 	pipe->map = map;
 
diff --git a/drivers/platform/msm/sps/spsi.h b/drivers/platform/msm/sps/spsi.h
index 4126999..8e4907b 100644
--- a/drivers/platform/msm/sps/spsi.h
+++ b/drivers/platform/msm/sps/spsi.h
@@ -28,6 +28,7 @@
 #include "sps_map.h"
 
 #define BAM_MAX_PIPES              31
+#define BAM_MAX_P_LOCK_GROUP_NUM   31
 
 /* Adjust for offset of struct sps_q_event */
 #define SPS_EVENT_INDEX(e)    ((e) - 1)
@@ -36,6 +37,9 @@
 /* BAM identifier used in log messages */
 #define BAM_ID(dev)       ((dev)->props.phys_addr)
 
+/* "Clear" value for the connection parameter struct */
+#define SPSRM_CLEAR     0xcccccccc
+
 #ifdef CONFIG_DEBUG_FS
 extern u8 debugfs_record_enabled;
 extern u8 logging_option;
@@ -127,6 +131,7 @@
 	u32 bam_phys;		/* Physical address of BAM. */
 	u32 pipe_index;		/* Pipe index */
 	u32 event_threshold;	/* Pipe event threshold */
+	u32 lock_group;	/* The lock group this pipe belongs to */
 	void *bam;
 };
 
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index cdc6c50..1454ca9 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1904,13 +1904,14 @@
 
 			turn_on_usb_ovp_fet(chip);
 		} else {
-			pm_chg_masked_write(chip, USB_OVP_CONTROL,
-						USB_OVP_DEBOUNCE_TIME, 0x1);
-			pr_debug("Exit count=%d chg_gone=%d, usb_valid=%d\n",
-					count, chg_gone, usb_chg_plugged_in);
-			return;
+			break;
 		}
 	}
+	pm_chg_masked_write(chip, USB_OVP_CONTROL,
+		USB_OVP_DEBOUNCE_TIME, 0x2);
+	pr_debug("Exit count=%d chg_gone=%d, usb_valid=%d\n",
+		count, chg_gone, usb_chg_plugged_in);
+	return;
 }
 
 static int find_usb_ma_value(int value)
@@ -2249,7 +2250,7 @@
 	pr_debug("fsm_state=%d reg_loop=0x%x\n",
 		pm_chg_get_fsm_state(data),
 		pm_chg_get_regulation_loop(data));
-	unplug_check_worker(&(chip->unplug_check_work.work));
+	schedule_work(&chip->unplug_check_work.work);
 	return IRQ_HANDLED;
 }
 
@@ -2326,15 +2327,23 @@
 static irqreturn_t chg_gone_irq_handler(int irq, void *data)
 {
 	struct pm8921_chg_chip *chip = data;
-	int chg_gone, usb_chg_plugged_in;
+	u8 reg;
+	int rc, chg_gone, usb_chg_plugged_in;
 
 	usb_chg_plugged_in = is_usb_chg_plugged_in(chip);
 	chg_gone = pm_chg_get_rt_status(chip, CHG_GONE_IRQ);
 
 	pr_debug("chg_gone=%d, usb_valid = %d\n", chg_gone, usb_chg_plugged_in);
+	pr_debug("Chg gone fsm_state=%d\n", pm_chg_get_fsm_state(data));
+
+	rc = pm8xxx_readb(chip->dev->parent, CHG_CNTRL_3, &reg);
+	if (rc)
+		pr_err("Failed to read CHG_CNTRL_3 rc=%d\n", rc);
+
+	if (reg & CHG_USB_SUSPEND_BIT)
+		return IRQ_HANDLED;
 	schedule_work(&chip->unplug_ovp_fet_open_work);
 
-	pr_debug("Chg gone fsm_state=%d\n", pm_chg_get_fsm_state(data));
 	power_supply_changed(&chip->batt_psy);
 	power_supply_changed(&chip->usb_psy);
 	return IRQ_HANDLED;
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index d63fddb..443f2df 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -426,7 +426,7 @@
 
 	/* replace driver_data with info */
 	info->regulator = regulator_register(&info->desc, &pdev->dev,
-					     pdata, info);
+					     pdata, info, NULL);
 	if (IS_ERR(info->regulator)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
 			info->desc.name);
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 74b1f71..7e529c7 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -4,6 +4,7 @@
 
 
 obj-$(CONFIG_REGULATOR) += core.o dummy.o
+obj-$(CONFIG_OF) += of_regulator.o
 obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
 obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 585e494..042271a 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -634,7 +634,7 @@
 		rdev = regulator_register(&ab3100_regulator_desc[i],
 					  &pdev->dev,
 					  &plfdata->reg_constraints[i],
-					  reg);
+					  reg, NULL);
 
 		if (IS_ERR(rdev)) {
 			err = PTR_ERR(rdev);
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 02f3c23..8b13b0e 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -821,7 +821,7 @@
 
 		/* register regulator with framework */
 		info->regulator = regulator_register(&info->desc, &pdev->dev,
-				&pdata->regulator[i], info);
+				&pdata->regulator[i], info, NULL);
 		if (IS_ERR(info->regulator)) {
 			err = PTR_ERR(info->regulator);
 			dev_err(&pdev->dev, "failed to register regulator %s\n",
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c
index a4be416..483c809 100644
--- a/drivers/regulator/ad5398.c
+++ b/drivers/regulator/ad5398.c
@@ -233,7 +233,7 @@
 	chip->current_mask = (chip->current_level - 1) << chip->current_offset;
 
 	chip->rdev = regulator_register(&ad5398_reg, &client->dev,
-					init_data, chip);
+					init_data, chip, NULL);
 	if (IS_ERR(chip->rdev)) {
 		ret = PTR_ERR(chip->rdev);
 		dev_err(&client->dev, "failed to register %s %s\n",
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index 068d488..dc4a8e6 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -106,7 +106,7 @@
 	ret = gpio_direction_output(pdata->gpio_nce, 1);
 
 	bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
-				     pdata->init_data, pdata);
+				     pdata->init_data, pdata, NULL);
 	if (IS_ERR(bq24022)) {
 		dev_dbg(&pdev->dev, "couldn't register regulator\n");
 		ret = PTR_ERR(bq24022);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2b58215..3f9beaa4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -27,6 +27,8 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
@@ -128,6 +130,33 @@
 	return NULL;
 }
 
+/**
+ * of_get_regulator - get a regulator device node based on supply name
+ * @dev: Device pointer for the consumer (of regulator) device
+ * @supply: regulator supply name
+ *
+ * Extract the regulator device node corresponding to the supply name.
+ * retruns the device node corresponding to the regulator if found, else
+ * returns NULL.
+ */
+static struct device_node *of_get_regulator(struct device *dev, const char *supply)
+{
+	struct device_node *regnode = NULL;
+	char prop_name[32]; /* 32 is max size of property name */
+
+	dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
+
+	snprintf(prop_name, 32, "%s-supply", supply);
+	regnode = of_parse_phandle(dev->of_node, prop_name, 0);
+
+	if (!regnode) {
+		dev_warn(dev, "%s property in node %s references invalid phandle",
+				prop_name, dev->of_node->full_name);
+		return NULL;
+	}
+	return regnode;
+}
+
 /* Platform voltage constraint check */
 static int regulator_check_voltage(struct regulator_dev *rdev,
 				   int *min_uV, int *max_uV)
@@ -1208,6 +1237,30 @@
 	return rdev->desc->ops->enable_time(rdev);
 }
 
+static struct regulator_dev *regulator_dev_lookup(struct device *dev,
+							 const char *supply)
+{
+	struct regulator_dev *r;
+	struct device_node *node;
+
+	/* first do a dt based lookup */
+	if (dev && dev->of_node) {
+		node = of_get_regulator(dev, supply);
+		if (node)
+			list_for_each_entry(r, &regulator_list, list)
+				if (r->dev.parent &&
+					node == r->dev.of_node)
+					return r;
+	}
+
+	/* if not found, try doing it non-dt way */
+	list_for_each_entry(r, &regulator_list, list)
+		if (strcmp(rdev_get_name(r), supply) == 0)
+			return r;
+
+	return NULL;
+}
+
 /* Internal regulator request function */
 static struct regulator *_regulator_get(struct device *dev, const char *id,
 					int exclusive)
@@ -1228,6 +1281,10 @@
 
 	mutex_lock(&regulator_list_mutex);
 
+	rdev = regulator_dev_lookup(dev, id);
+	if (rdev)
+		goto found;
+
 	list_for_each_entry(map, &regulator_map_list, list) {
 		/* If the mapping has a device set up it must match */
 		if (map->dev_name &&
@@ -3080,11 +3137,12 @@
  */
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 	struct device *dev, const struct regulator_init_data *init_data,
-	void *driver_data)
+	void *driver_data, struct device_node *of_node)
 {
 	static atomic_t regulator_no = ATOMIC_INIT(0);
 	struct regulator_dev *rdev;
 	int ret, i;
+	const char *supply = NULL;
 
 	if (regulator_desc == NULL)
 		return ERR_PTR(-EINVAL);
@@ -3140,6 +3198,7 @@
 
 	/* register with sysfs */
 	rdev->dev.class = &regulator_class;
+	rdev->dev.of_node = of_node;
 	rdev->dev.parent = dev;
 	dev_set_name(&rdev->dev, "regulator.%d",
 		     atomic_inc_return(&regulator_no) - 1);
@@ -3161,21 +3220,18 @@
 	if (ret < 0)
 		goto scrub;
 
-	if (init_data->supply_regulator) {
+	if (init_data->supply_regulator)
+		supply = init_data->supply_regulator;
+	else if (regulator_desc->supply_name)
+		supply = regulator_desc->supply_name;
+
+	if (supply) {
 		struct regulator_dev *r;
-		int found = 0;
 
-		list_for_each_entry(r, &regulator_list, list) {
-			if (strcmp(rdev_get_name(r),
-				   init_data->supply_regulator) == 0) {
-				found = 1;
-				break;
-			}
-		}
+		r = regulator_dev_lookup(dev, supply);
 
-		if (!found) {
-			dev_err(dev, "Failed to find supply %s\n",
-				init_data->supply_regulator);
+		if (!r) {
+			dev_err(dev, "Failed to find supply %s\n", supply);
 			ret = -ENODEV;
 			goto scrub;
 		}
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index 362e082..f3064fe 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -536,7 +536,7 @@
 		ri->desc.ops = &da9030_regulator_ldo1_15_ops;
 
 	rdev = regulator_register(&ri->desc, &pdev->dev,
-				  pdev->dev.platform_data, ri);
+				  pdev->dev.platform_data, ri, NULL);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
 				ri->desc.name);
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c
index 2bb8f45..f88b13d 100644
--- a/drivers/regulator/db8500-prcmu.c
+++ b/drivers/regulator/db8500-prcmu.c
@@ -485,7 +485,7 @@
 
 		/* register with the regulator framework */
 		info->rdev = regulator_register(&info->desc, &pdev->dev,
-				init_data, info);
+				init_data, info, NULL);
 		if (IS_ERR(info->rdev)) {
 			err = PTR_ERR(info->rdev);
 			dev_err(&pdev->dev, "failed to register %s: err %i\n",
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c
index c7410bd..910583f 100644
--- a/drivers/regulator/dummy.c
+++ b/drivers/regulator/dummy.c
@@ -36,6 +36,29 @@
 	.ops = &dummy_ops,
 };
 
+static int __devinit dummy_regulator_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
+						  &dummy_initdata, NULL, NULL);
+	if (IS_ERR(dummy_regulator_rdev)) {
+		ret = PTR_ERR(dummy_regulator_rdev);
+		pr_err("Failed to register regulator: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct platform_driver dummy_regulator_driver = {
+	.probe		= dummy_regulator_probe,
+	.driver		= {
+		.name		= "reg-dummy",
+		.owner		= THIS_MODULE,
+	},
+};
+
 static struct platform_device *dummy_pdev;
 
 void __init regulator_dummy_init(void)
@@ -55,12 +78,9 @@
 		return;
 	}
 
-	dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
-						  &dummy_initdata, NULL);
-	if (IS_ERR(dummy_regulator_rdev)) {
-		ret = PTR_ERR(dummy_regulator_rdev);
-		pr_err("Failed to register regulator: %d\n", ret);
+	ret = platform_driver_register(&dummy_regulator_driver);
+	if (ret != 0) {
+		pr_err("Failed to register dummy regulator driver: %d\n", ret);
 		platform_device_unregister(dummy_pdev);
-		return;
 	}
 }
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 2fe9d99c..906b265 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -26,6 +26,10 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
 
 struct fixed_voltage_data {
 	struct regulator_desc desc;
@@ -37,6 +41,53 @@
 	bool is_enabled;
 };
 
+
+/**
+ * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
+ * @dev: device requesting for fixed_voltage_config
+ *
+ * Populates fixed_voltage_config structure by extracting data from device
+ * tree node, returns a pointer to the populated structure of NULL if memory
+ * alloc fails.
+ */
+struct fixed_voltage_config *of_get_fixed_voltage_config(struct device *dev)
+{
+	struct fixed_voltage_config *config;
+	struct device_node *np = dev->of_node;
+	const __be32 *delay;
+	struct regulator_init_data *init_data;
+
+	config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
+								 GFP_KERNEL);
+	if (!config)
+		return NULL;
+
+	config->init_data = of_get_regulator_init_data(dev);
+	init_data = config->init_data;
+
+	config->supply_name = init_data->constraints.name;
+	if (init_data->constraints.min_uV == init_data->constraints.max_uV) {
+		config->microvolts = init_data->constraints.min_uV;
+	} else {
+		dev_err(dev,
+			 "Fixed regulator specified with variable voltages\n");
+		return NULL;
+	}
+
+	if (init_data->constraints.boot_on)
+		config->enabled_at_boot = true;
+
+	config->gpio = of_get_named_gpio(np, "gpio", 0);
+	delay = of_get_property(np, "startup-delay-us", NULL);
+	if (delay)
+		config->startup_delay = be32_to_cpu(*delay);
+
+	if (of_find_property(np, "enable-active-high", NULL))
+		config->enable_high = true;
+
+	return config;
+}
+
 static int fixed_voltage_is_enabled(struct regulator_dev *dev)
 {
 	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
@@ -108,6 +159,9 @@
 	struct fixed_voltage_data *drvdata;
 	int ret;
 
+	if (pdev->dev.of_node)
+		config = of_get_fixed_voltage_config(&pdev->dev);
+
 	drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
 	if (drvdata == NULL) {
 		dev_err(&pdev->dev, "Failed to allocate device data\n");
@@ -179,7 +233,7 @@
 	}
 
 	drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
-					  config->init_data, drvdata);
+					  config->init_data, drvdata, NULL);
 	if (IS_ERR(drvdata->dev)) {
 		ret = PTR_ERR(drvdata->dev);
 		dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
@@ -216,12 +270,23 @@
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id fixed_of_match[] __devinitconst = {
+	{ .compatible = "regulator-fixed", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, fixed_of_match);
+#else
+#define fixed_of_match NULL
+#endif
+
 static struct platform_driver regulator_fixed_voltage_driver = {
 	.probe		= reg_fixed_voltage_probe,
 	.remove		= __devexit_p(reg_fixed_voltage_remove),
 	.driver		= {
 		.name		= "reg-fixed-voltage",
 		.owner		= THIS_MODULE,
+		.of_match_table = fixed_of_match,
 	},
 };
 
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c
index b91e32f..1fd390c 100644
--- a/drivers/regulator/gpio-regulator.c
+++ b/drivers/regulator/gpio-regulator.c
@@ -152,7 +152,7 @@
 	vreg->desc.owner	= THIS_MODULE;
 
 	vreg->rdev = regulator_register(&vreg->desc, &pdev->dev,
-					&pdata->init_data, vreg);
+					&pdata->init_data, vreg, NULL);
 	if (IS_ERR(vreg->rdev)) {
 		rc = PTR_ERR(vreg->rdev);
 		pr_err("%s: regulator_register failed, rc=%d.\n", vreg->name,
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c
index e4b3592..c1a456c 100644
--- a/drivers/regulator/isl6271a-regulator.c
+++ b/drivers/regulator/isl6271a-regulator.c
@@ -170,7 +170,7 @@
 
 	for (i = 0; i < 3; i++) {
 		pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev,
-						init_data, pmic);
+						init_data, pmic, NULL);
 		if (IS_ERR(pmic->rdev[i])) {
 			dev_err(&i2c->dev, "failed to register %s\n", id->name);
 			err = PTR_ERR(pmic->rdev[i]);
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index 0f22ef1..42b1a30 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -450,7 +450,7 @@
 	for (i = 0; i < pdata->num_regulators; i++) {
 		struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
 		lp3971->rdev[i] = regulator_register(&regulators[reg->id],
-					lp3971->dev, reg->initdata, lp3971);
+				lp3971->dev, reg->initdata, lp3971, NULL);
 
 		if (IS_ERR(lp3971->rdev[i])) {
 			err = PTR_ERR(lp3971->rdev[i]);
diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c
index 6aa1b50..939e7f4 100644
--- a/drivers/regulator/lp3972.c
+++ b/drivers/regulator/lp3972.c
@@ -554,7 +554,7 @@
 	for (i = 0; i < pdata->num_regulators; i++) {
 		struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
 		lp3972->rdev[i] = regulator_register(&regulators[reg->id],
-					lp3972->dev, reg->initdata, lp3972);
+				lp3972->dev, reg->initdata, lp3972, NULL);
 
 		if (IS_ERR(lp3972->rdev[i])) {
 			err = PTR_ERR(lp3972->rdev[i]);
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index 3f49512..40e7a4d 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -214,7 +214,7 @@
 		}
 		rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
 					     pdata->subdevs[i].platform_data,
-					     max1586);
+					     max1586, NULL);
 		if (IS_ERR(rdev[i])) {
 			ret = PTR_ERR(rdev[i]);
 			dev_err(&client->dev, "failed to register %s\n",
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index 30eb9e5..14d6d28 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -347,7 +347,7 @@
 	}
 
 	info->regulator = regulator_register(&dcdc_desc, &client->dev,
-					     pdata->regulator, info);
+					     pdata->regulator, info, NULL);
 	if (IS_ERR(info->regulator)) {
 		dev_err(info->dev, "failed to register regulator %s\n",
 			dcdc_desc.name);
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
index 33f5d9a..a838e66 100644
--- a/drivers/regulator/max8660.c
+++ b/drivers/regulator/max8660.c
@@ -449,7 +449,7 @@
 
 		rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
 					     pdata->subdevs[i].platform_data,
-					     max8660);
+					     max8660, NULL);
 		if (IS_ERR(rdev[i])) {
 			ret = PTR_ERR(rdev[i]);
 			dev_err(&client->dev, "failed to register %s\n",
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
index e4dbd66..dd5fae9 100644
--- a/drivers/regulator/max8925-regulator.c
+++ b/drivers/regulator/max8925-regulator.c
@@ -265,7 +265,7 @@
 	ri->chip = chip;
 
 	rdev = regulator_register(&ri->desc, &pdev->dev,
-				  pdata->regulator[pdev->id], ri);
+				  pdata->regulator[pdev->id], ri, NULL);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
 				ri->desc.name);
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c
index 486ed81..c4bfd4d 100644
--- a/drivers/regulator/max8952.c
+++ b/drivers/regulator/max8952.c
@@ -211,7 +211,7 @@
 	mutex_init(&max8952->mutex);
 
 	max8952->rdev = regulator_register(&regulator, max8952->dev,
-			&pdata->reg_data, max8952);
+			&pdata->reg_data, max8952, NULL);
 
 	if (IS_ERR(max8952->rdev)) {
 		ret = PTR_ERR(max8952->rdev);
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index ad6628c..f701ca5 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -1145,7 +1145,7 @@
 			regulators[id].n_voltages = 16;
 
 		rdev[i] = regulator_register(&regulators[id], max8997->dev,
-				pdata->regulators[i].initdata, max8997);
+				pdata->regulators[i].initdata, max8997, NULL);
 		if (IS_ERR(rdev[i])) {
 			ret = PTR_ERR(rdev[i]);
 			dev_err(max8997->dev, "regulator init failed for %d\n",
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 41a1495..2d38c24 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -847,7 +847,7 @@
 			regulators[index].n_voltages = count;
 		}
 		rdev[i] = regulator_register(&regulators[index], max8998->dev,
-				pdata->regulators[i].initdata, max8998);
+				pdata->regulators[i].initdata, max8998, NULL);
 		if (IS_ERR(rdev[i])) {
 			ret = PTR_ERR(rdev[i]);
 			dev_err(max8998->dev, "regulator init failed\n");
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index 730f43a..8d5822b 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -356,7 +356,7 @@
 		init_data = &pdata->regulators[i];
 		priv->regulators[i] = regulator_register(
 				&mc13783_regulators[init_data->id].desc,
-				&pdev->dev, init_data->init_data, priv);
+				&pdev->dev, init_data->init_data, priv, NULL);
 
 		if (IS_ERR(priv->regulators[i])) {
 			dev_err(&pdev->dev, "failed to register regulator %s\n",
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c
index 3285d41..9d82b5c 100644
--- a/drivers/regulator/mc13892-regulator.c
+++ b/drivers/regulator/mc13892-regulator.c
@@ -572,7 +572,7 @@
 		init_data = &pdata->regulators[i];
 		priv->regulators[i] = regulator_register(
 			&mc13892_regulators[init_data->id].desc,
-			&pdev->dev, init_data->init_data, priv);
+			&pdev->dev, init_data->init_data, priv, NULL);
 
 		if (IS_ERR(priv->regulators[i])) {
 			dev_err(&pdev->dev, "failed to register regulator %s\n",
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
new file mode 100644
index 0000000..76673c7
--- /dev/null
+++ b/drivers/regulator/of_regulator.c
@@ -0,0 +1,81 @@
+/*
+ * OF helpers for regulator framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/regulator/machine.h>
+
+static void of_get_regulation_constraints(struct device_node *np,
+					struct regulator_init_data **init_data)
+{
+	const __be32 *min_uV, *max_uV, *uV_offset;
+	const __be32 *min_uA, *max_uA;
+	struct regulation_constraints *constraints = &(*init_data)->constraints;
+
+	constraints->name = of_get_property(np, "regulator-name", NULL);
+
+	min_uV = of_get_property(np, "regulator-min-microvolt", NULL);
+	if (min_uV)
+		constraints->min_uV = be32_to_cpu(*min_uV);
+	max_uV = of_get_property(np, "regulator-max-microvolt", NULL);
+	if (max_uV)
+		constraints->max_uV = be32_to_cpu(*max_uV);
+
+	/* Voltage change possible? */
+	if (constraints->min_uV != constraints->max_uV)
+		constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
+
+	uV_offset = of_get_property(np, "regulator-microvolt-offset", NULL);
+	if (uV_offset)
+		constraints->uV_offset = be32_to_cpu(*uV_offset);
+	min_uA = of_get_property(np, "regulator-min-microamp", NULL);
+	if (min_uA)
+		constraints->min_uA = be32_to_cpu(*min_uA);
+	max_uA = of_get_property(np, "regulator-max-microamp", NULL);
+	if (max_uA)
+		constraints->max_uA = be32_to_cpu(*max_uA);
+
+	/* Current change possible? */
+	if (constraints->min_uA != constraints->max_uA)
+		constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
+
+	if (of_find_property(np, "regulator-boot-on", NULL))
+		constraints->boot_on = true;
+
+	if (of_find_property(np, "regulator-always-on", NULL))
+		constraints->always_on = true;
+	else /* status change should be possible if not always on. */
+		constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
+}
+
+/**
+ * of_get_regulator_init_data - extract regulator_init_data structure info
+ * @dev: device requesting for regulator_init_data
+ *
+ * Populates regulator_init_data structure by extracting data from device
+ * tree node, returns a pointer to the populated struture or NULL if memory
+ * alloc fails.
+ */
+struct regulator_init_data *of_get_regulator_init_data(struct device *dev)
+{
+	struct regulator_init_data *init_data;
+
+	if (!dev->of_node)
+		return NULL;
+
+	init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
+	if (!init_data)
+		return NULL; /* Out of memory? */
+
+	of_get_regulation_constraints(dev->of_node, &init_data);
+	return init_data;
+}
diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c
index 31f6e11..a5aab1b 100644
--- a/drivers/regulator/pcap-regulator.c
+++ b/drivers/regulator/pcap-regulator.c
@@ -277,7 +277,7 @@
 	void *pcap = dev_get_drvdata(pdev->dev.parent);
 
 	rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev,
-				pdev->dev.platform_data, pcap);
+				pdev->dev.platform_data, pcap, NULL);
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
 
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 69a11d9..1d1c310 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -320,7 +320,7 @@
 	pcf = dev_to_pcf50633(pdev->dev.parent);
 
 	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-				  pdev->dev.platform_data, pcf);
+				  pdev->dev.platform_data, pcf, NULL);
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
 
diff --git a/drivers/regulator/pm8058-xo.c b/drivers/regulator/pm8058-xo.c
index b778660..90093dd 100644
--- a/drivers/regulator/pm8058-xo.c
+++ b/drivers/regulator/pm8058-xo.c
@@ -162,7 +162,7 @@
 			goto bail;
 
 		xo->rdev = regulator_register(rdesc, &pdev->dev,
-					&xo->pdata->init_data, xo);
+					&xo->pdata->init_data, xo, NULL);
 		if (IS_ERR(xo->rdev)) {
 			rc = PTR_ERR(xo->rdev);
 			pr_err("FAIL: regulator_register(%s): rc=%d\n",
diff --git a/drivers/regulator/pm8xxx-regulator.c b/drivers/regulator/pm8xxx-regulator.c
index fd691f0..833c513 100644
--- a/drivers/regulator/pm8xxx-regulator.c
+++ b/drivers/regulator/pm8xxx-regulator.c
@@ -3206,7 +3206,7 @@
 
 	if (!core_data->is_pin_controlled) {
 		vreg->rdev = regulator_register(rdesc, &pdev->dev,
-				&(pdata->init_data), vreg);
+				&(pdata->init_data), vreg, NULL);
 		if (IS_ERR(vreg->rdev)) {
 			rc = PTR_ERR(vreg->rdev);
 			vreg->rdev = NULL;
@@ -3215,7 +3215,7 @@
 		}
 	} else {
 		vreg->rdev_pc = regulator_register(rdesc, &pdev->dev,
-				&(pdata->init_data), vreg);
+				&(pdata->init_data), vreg, NULL);
 		if (IS_ERR(vreg->rdev_pc)) {
 			rc = PTR_ERR(vreg->rdev_pc);
 			vreg->rdev_pc = NULL;
diff --git a/drivers/regulator/pmic8058-regulator.c b/drivers/regulator/pmic8058-regulator.c
index e137b0f..01f4abf 100644
--- a/drivers/regulator/pmic8058-regulator.c
+++ b/drivers/regulator/pmic8058-regulator.c
@@ -1692,7 +1692,7 @@
 			      &= ~(REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE);
 
 		vreg->rdev = regulator_register(rdesc, &pdev->dev,
-				&vreg->pdata->init_data, vreg);
+				&vreg->pdata->init_data, vreg, NULL);
 		if (IS_ERR(vreg->rdev)) {
 			rc = PTR_ERR(vreg->rdev);
 			pr_err("%s: regulator_register failed for %s, rc=%d\n",
diff --git a/drivers/regulator/pmic8901-regulator.c b/drivers/regulator/pmic8901-regulator.c
index 6fd0a05..72894ba 100644
--- a/drivers/regulator/pmic8901-regulator.c
+++ b/drivers/regulator/pmic8901-regulator.c
@@ -954,7 +954,7 @@
 			      &= ~(REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE);
 
 		vreg->rdev = regulator_register(rdesc, &pdev->dev,
-				&vreg->pdata->init_data, vreg);
+				&vreg->pdata->init_data, vreg, NULL);
 		if (IS_ERR(vreg->rdev)) {
 			rc = PTR_ERR(vreg->rdev);
 			pr_err("%s: regulator_register failed for %s, rc=%d\n",
diff --git a/drivers/regulator/stub-regulator.c b/drivers/regulator/stub-regulator.c
index 5b44c04..6198c40 100644
--- a/drivers/regulator/stub-regulator.c
+++ b/drivers/regulator/stub-regulator.c
@@ -182,7 +182,7 @@
 	vreg_priv->voltage = vreg_pdata->init_data.constraints.min_uV;
 
 	vreg_priv->rdev = regulator_register(rdesc, &pdev->dev,
-			&(vreg_pdata->init_data), vreg_priv);
+			&(vreg_pdata->init_data), vreg_priv, NULL);
 	if (IS_ERR(vreg_priv->rdev)) {
 		rc = PTR_ERR(vreg_priv->rdev);
 		vreg_priv->rdev = NULL;
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
index 1011873..d9278da 100644
--- a/drivers/regulator/tps6105x-regulator.c
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -151,7 +151,8 @@
 	/* Register regulator with framework */
 	tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
 					     &tps6105x->client->dev,
-					     pdata->regulator_data, tps6105x);
+					     pdata->regulator_data, tps6105x,
+					     NULL);
 	if (IS_ERR(tps6105x->regulator)) {
 		ret = PTR_ERR(tps6105x->regulator);
 		dev_err(&tps6105x->client->dev,
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index fbddc15..8efb772 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -507,7 +507,7 @@
 
 		/* Register the regulators */
 		rdev = regulator_register(&tps->desc[i], &client->dev,
-					  init_data, tps);
+					  init_data, tps, NULL);
 		if (IS_ERR(rdev)) {
 			dev_err(&client->dev, "failed to register %s\n",
 				id->name);
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index bfffabc..0f86e56 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -605,7 +605,7 @@
 		tps->desc[i].owner = THIS_MODULE;
 
 		rdev = regulator_register(&tps->desc[i],
-					tps6507x_dev->dev, init_data, tps);
+					tps6507x_dev->dev, init_data, tps, NULL);
 		if (IS_ERR(rdev)) {
 			dev_err(tps6507x_dev->dev,
 				"failed to register %s regulator\n",
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c
index 9166aa0..70b7b1f 100644
--- a/drivers/regulator/tps6524x-regulator.c
+++ b/drivers/regulator/tps6524x-regulator.c
@@ -651,7 +651,7 @@
 			hw->desc[i].n_voltages = 1;
 
 		hw->rdev[i] = regulator_register(&hw->desc[i], dev,
-						 init_data, hw);
+						 init_data, hw, NULL);
 		if (IS_ERR(hw->rdev[i])) {
 			ret = PTR_ERR(hw->rdev[i]);
 			hw->rdev[i] = NULL;
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index bb04a75..6a35c3a 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -365,7 +365,7 @@
 		return err;
 
 	rdev = regulator_register(&ri->desc, &pdev->dev,
-				  pdev->dev.platform_data, ri);
+				  pdev->dev.platform_data, ri, NULL);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
 				ri->desc.name);
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 425aab3..e436dcd 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -939,7 +939,7 @@
 		pmic->desc[i].owner = THIS_MODULE;
 
 		rdev = regulator_register(&pmic->desc[i],
-				tps65910->dev, reg_data, pmic);
+				tps65910->dev, reg_data, pmic, NULL);
 		if (IS_ERR(rdev)) {
 			dev_err(tps65910->dev,
 				"failed to register %s regulator\n",
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 87fe0f7..1c12070 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -1074,7 +1074,7 @@
 		break;
 	}
 
-	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, NULL);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "can't register %s, %ld\n",
 				info->desc.name, PTR_ERR(rdev));
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index a0982e8..38bb80d 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -556,7 +556,7 @@
 		wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
 
 	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-					     pdata->dcdc[id], dcdc);
+					     pdata->dcdc[id], dcdc, NULL);
 	if (IS_ERR(dcdc->regulator)) {
 		ret = PTR_ERR(dcdc->regulator);
 		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -744,7 +744,7 @@
 	dcdc->desc.owner = THIS_MODULE;
 
 	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-					     pdata->dcdc[id], dcdc);
+					     pdata->dcdc[id], dcdc, NULL);
 	if (IS_ERR(dcdc->regulator)) {
 		ret = PTR_ERR(dcdc->regulator);
 		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -871,7 +871,7 @@
 	dcdc->desc.owner = THIS_MODULE;
 
 	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-					     pdata->dcdc[id], dcdc);
+					     pdata->dcdc[id], dcdc, NULL);
 	if (IS_ERR(dcdc->regulator)) {
 		ret = PTR_ERR(dcdc->regulator);
 		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -970,7 +970,7 @@
 	dcdc->desc.owner = THIS_MODULE;
 
 	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-					     pdata->epe[id], dcdc);
+					     pdata->epe[id], dcdc, NULL);
 	if (IS_ERR(dcdc->regulator)) {
 		ret = PTR_ERR(dcdc->regulator);
 		dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 01f27c7..d3ad3f5 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -189,7 +189,7 @@
 	isink->desc.owner = THIS_MODULE;
 
 	isink->regulator = regulator_register(&isink->desc, &pdev->dev,
-					     pdata->isink[id], isink);
+					     pdata->isink[id], isink, NULL);
 	if (IS_ERR(isink->regulator)) {
 		ret = PTR_ERR(isink->regulator);
 		dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n",
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 2220cf8..d0fe563 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -345,7 +345,7 @@
 	ldo->desc.owner = THIS_MODULE;
 
 	ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-					     pdata->ldo[id], ldo);
+					     pdata->ldo[id], ldo, NULL);
 	if (IS_ERR(ldo->regulator)) {
 		ret = PTR_ERR(ldo->regulator);
 		dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@@ -609,7 +609,7 @@
 	ldo->desc.owner = THIS_MODULE;
 
 	ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-					     pdata->ldo[id], ldo);
+					     pdata->ldo[id], ldo, NULL);
 	if (IS_ERR(ldo->regulator)) {
 		ret = PTR_ERR(ldo->regulator);
 		dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@@ -799,7 +799,7 @@
 	ldo->desc.owner = THIS_MODULE;
 
 	ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-					     pdata->ldo[id], ldo);
+					     pdata->ldo[id], ldo, NULL);
 	if (IS_ERR(ldo->regulator)) {
 		ret = PTR_ERR(ldo->regulator);
 		dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 1bcb22c..6894009 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1428,7 +1428,7 @@
 	/* register regulator */
 	rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
 				  pdev->dev.platform_data,
-				  dev_get_drvdata(&pdev->dev));
+				  dev_get_drvdata(&pdev->dev), NULL);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register %s\n",
 			wm8350_reg[pdev->id].name);
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 0f12c70..f468f8a 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -325,7 +325,7 @@
 	struct regulator_dev *rdev;
 
 	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-				  pdev->dev.platform_data, wm8400);
+				  pdev->dev.platform_data, wm8400, NULL);
 
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index 35b2958..6f3132c 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -256,7 +256,7 @@
 		ldo->is_enabled = true;
 
 	ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
-					     pdata->ldo[id].init_data, ldo);
+					     pdata->ldo[id].init_data, ldo, NULL);
 	if (IS_ERR(ldo->regulator)) {
 		ret = PTR_ERR(ldo->regulator);
 		dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 2aab31e..8bd5bd8 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -22,6 +22,8 @@
 #include <linux/kthread.h>
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_slimbus.h>
 #include <mach/sps.h>
 
 /* Per spec.max 40 bytes per received message */
@@ -1868,7 +1870,24 @@
 		ret = -ENOMEM;
 		goto err_ioremap_bam_failed;
 	}
-	dev->ctrl.nr = pdev->id;
+	if (pdev->dev.of_node) {
+
+		ret = of_property_read_u32(pdev->dev.of_node, "cell-index",
+					&dev->ctrl.nr);
+		if (ret) {
+			dev_err(&pdev->dev, "Cell index not specified:%d", ret);
+			goto err_of_init_failed;
+		}
+		/* Optional properties */
+		ret = of_property_read_u32(pdev->dev.of_node,
+					"qcom,min-clk-gear", &dev->ctrl.min_cg);
+		ret = of_property_read_u32(pdev->dev.of_node,
+					"qcom,max-clk-gear", &dev->ctrl.max_cg);
+		pr_err("min_cg:%d, max_cg:%d, ret:%d", dev->ctrl.min_cg,
+					dev->ctrl.max_cg, ret);
+	} else {
+		dev->ctrl.nr = pdev->id;
+	}
 	dev->ctrl.nchans = MSM_SLIM_NCHANS;
 	dev->ctrl.nports = MSM_SLIM_NPORTS;
 	dev->ctrl.set_laddr = msm_set_laddr;
@@ -1901,6 +1920,7 @@
 	dev->ctrl.a_framer = &dev->framer;
 	dev->ctrl.clkgear = SLIM_MAX_CLK_GEAR;
 	dev->ctrl.dev.parent = &pdev->dev;
+	dev->ctrl.dev.of_node = pdev->dev.of_node;
 
 	ret = request_irq(dev->irq, msm_slim_interrupt, IRQF_TRIGGER_HIGH,
 				"msm_slim_irq", dev);
@@ -1995,6 +2015,9 @@
 	 * function
 	 */
 	mb();
+	if (pdev->dev.of_node)
+		of_register_slim_devices(&dev->ctrl);
+
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, MSM_SLIM_AUTOSUSPEND);
 	pm_runtime_set_active(&pdev->dev);
@@ -2009,6 +2032,7 @@
 err_request_irq_failed:
 	msm_slim_sps_exit(dev);
 err_sps_init_failed:
+err_of_init_failed:
 	iounmap(dev->bam.base);
 err_ioremap_bam_failed:
 	iounmap(dev->base);
@@ -2162,6 +2186,13 @@
 	)
 };
 
+static struct of_device_id msm_slim_dt_match[] = {
+	{
+		.compatible = "qcom,slim-msm",
+	},
+	{}
+};
+
 static struct platform_driver msm_slim_driver = {
 	.probe = msm_slim_probe,
 	.remove = msm_slim_remove,
@@ -2169,6 +2200,7 @@
 		.name = MSM_SLIM_NAME,
 		.owner = THIS_MODULE,
 		.pm = &msm_slim_dev_pm_ops,
+		.of_match_table = msm_slim_dt_match,
 	},
 };
 
diff --git a/drivers/staging/qcache/qcache-main.c b/drivers/staging/qcache/qcache-main.c
index e3a95e0..ea6635c 100644
--- a/drivers/staging/qcache/qcache-main.c
+++ b/drivers/staging/qcache/qcache-main.c
@@ -160,15 +160,18 @@
 
 	spin_lock_irqsave(&qc->lock, flags);
 	offset = bitmap_find_free_region(qc->bitmap, qc->pages, 0);
-	spin_unlock_irqrestore(&qc->lock, flags);
 
-	if (offset < 0)
+	if (offset < 0) {
+		spin_unlock_irqrestore(&qc->lock, flags);
 		return NULL;
+	}
 
-	addr = qc->addr + offset * PAGE_SIZE;
 	zcache_qc_allocated++;
 	zcache_qc_used++;
 	zcache_qc_max_used = max(zcache_qc_max_used, zcache_qc_used);
+	spin_unlock_irqrestore(&qc->lock, flags);
+
+	addr = qc->addr + offset * PAGE_SIZE;
 
 	return addr;
 }
@@ -183,10 +186,10 @@
 
 	spin_lock_irqsave(&qc->lock, flags);
 	bitmap_release_region(qc->bitmap, offset, 0);
-	spin_unlock_irqrestore(&qc->lock, flags);
 
 	zcache_qc_freed++;
 	zcache_qc_used--;
+	spin_unlock_irqrestore(&qc->lock, flags);
 }
 
 /*
@@ -737,26 +740,21 @@
 {
 	struct tmem_pool *pool;
 	int pool_id;
+	struct zcache_preload *kp;
+
+	kp = &__get_cpu_var(zcache_preloads);
 
 	for (pool_id = 0; pool_id < MAX_POOLS_PER_CLIENT; pool_id++) {
 		pool = zcache_get_pool_by_id(LOCAL_CLIENT, pool_id);
 		tmem_flush_pool(pool);
 	}
-}
-
-static void reset_qcache(void)
-{
-	struct qcache_info *qc = &qcache_info;
-	int bitmap_size;
-	struct zcache_preload *kp;
-
-	bitmap_size = BITS_TO_LONGS(qc->pages) * sizeof(long);
-	memset(qc->bitmap, 0, bitmap_size);
-	zcache_qc_used = 0;
-	zcache_qc_freed = zcache_qc_allocated;
-
-	kp = &__get_cpu_var(zcache_preloads);
-	kp->page = NULL;
+	if (kp->page) {
+		qcache_free(kp->page);
+		kp->page = NULL;
+	}
+	if (zcache_qc_used)
+		pr_warn("pages used not 0 after qcache flush all, is %ld\n",
+			zcache_qc_used);
 }
 
 /*
@@ -771,9 +769,6 @@
 static void zcache_control(bool freeze)
 {
 	zcache_freeze = freeze;
-
-	if (freeze)
-		reset_qcache();
 }
 
 static struct tmem_hostops zcache_hostops = {
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
index 593d1db..5607ac4 100644
--- a/drivers/usb/dwc3/Makefile
+++ b/drivers/usb/dwc3/Makefile
@@ -4,10 +4,7 @@
 obj-$(CONFIG_USB_DWC3)			+= dwc3.o
 
 dwc3-y					:= core.o
-
-ifneq ($(CONFIG_USB_GADGET_DWC3),)
-	dwc3-y				+= gadget.o ep0.o
-endif
+dwc3-y					+= gadget.o ep0.o
 
 ifneq ($(CONFIG_DEBUG_FS),)
 	dwc3-y				+= debugfs.o
@@ -28,7 +25,7 @@
 # PCI doesn't provide nops if CONFIG_PCI isn't enabled.
 ##
 
-obj-$(CONFIG_USB_DWC3)		+= dwc3-omap.o
+obj-$(CONFIG_USB_DWC3_OMAP)	+= dwc3-omap.o
 
 ifneq ($(CONFIG_PCI),)
 	obj-$(CONFIG_USB_DWC3)		+= dwc3-pci.o
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 71145a4..9206096 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -110,7 +110,7 @@
 	list_move_tail(&req->list, &dep->req_queued);
 }
 
-#if defined(CONFIG_USB_GADGET_DWC3) || defined(CONFIG_USB_GADGET_DWC3_MODULE)
+#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_DWC3_MODULE)
 int dwc3_gadget_init(struct dwc3 *dwc);
 void dwc3_gadget_exit(struct dwc3 *dwc);
 #else
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 0865f91..f8327c8 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -300,17 +300,6 @@
 	  PXA9xx Processor series include a high speed USB2.0 device
 	  controller, which support high speed and full speed USB peripheral.
 
-config USB_GADGET_DWC3
-	tristate "DesignWare USB3.0 (DRD) Controller"
-	depends on USB_DWC3
-	select USB_GADGET_DUALSPEED
-	select USB_GADGET_SUPERSPEED
-	help
-	  DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller
-	  which can be configured for peripheral-only, host-only, hub-only
-	  and Dual-Role operation. This Controller was first integrated into
-	  the OMAP5 series of processors. More information about the OMAP5
-	  version of this controller, refer to http://www.ti.com/omap5.
 #
 # Controllers available in both integrated and discrete versions
 #
@@ -476,6 +465,32 @@
 	  dynamically linked module called "ci13xxx_msm_hsic" and force all
 	  gadget drivers to also be dynamically linked.
 
+config USB_DWC3_MSM
+	tristate "DesignWare USB3.0 (DRD) Controller for MSM"
+	depends on ARCH_MSM
+	select USB_DWC3
+	select USB_GADGET_DUALSPEED
+	select USB_GADGET_SELECTED
+	help
+	  The DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller
+	  integrated into the Qualcomm MSM chipset series, supporting host,
+	  device and otg modes of operation. For more information please
+	  refer to http://www.qualcomm.com/chipsets.
+
+config USB_DWC3_OMAP
+	tristate "DesignWare USB3.0 (DRD) Controller for OMAP"
+	depends on ARCH_OMAP
+	select USB_DWC3
+	select USB_GADGET_DUALSPEED
+	select USB_GADGET_SUPERSPEED
+	select USB_GADGET_SELECTED
+	help
+	  DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller
+	  which can be configured for peripheral-only, host-only, hub-only
+	  and Dual-Role operation. This Controller was first integrated into
+	  the OMAP5 series of processors. More information about the OMAP5
+	  version of this controller, refer to http://www.ti.com/omap5.
+
 #
 # LAST -- dummy/emulated controller
 #
@@ -527,9 +542,15 @@
 
 # Selected by UDC drivers that support super-speed opperation
 config USB_GADGET_SUPERSPEED
-	bool
+	bool "Operate as superspeed"
 	depends on USB_GADGET
 	depends on USB_GADGET_DUALSPEED
+	default n
+	help
+	 When a superspeed peripheral controller is selected
+	 (for example DesignWare USB3.0 controller), use this flag to
+	 indicate if the device should operate in superspeed(=y)
+	 or not.
 
 #
 # USB Gadget Drivers
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 28e217b..e0fc12c 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -2,7 +2,7 @@
  * Driver for HighSpeed USB Client Controller in MSM7K
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  * Author: Mike Lockwood <lockwood@android.com>
  *         Brian Swetland <swetland@google.com>
  *
@@ -1109,7 +1109,6 @@
 	struct msm_endpoint *ept = ui->ept + bit;
 	struct msm_request *req;
 	unsigned long flags;
-	int req_dequeue = 1;
 	unsigned info;
 
 	/*
@@ -1129,23 +1128,12 @@
 			break;
 		}
 
-dequeue:
 		/* clean speculative fetches on req->item->info */
 		dma_coherent_post_ops();
 		info = req->item->info;
 		/* if the transaction is still in-flight, stop here */
-		if (info & INFO_ACTIVE) {
-			if (req_dequeue) {
-				req_dequeue = 0;
-				ui->dTD_update_fail_count++;
-				ept->dTD_update_fail_count++;
-				udelay(10);
-				goto dequeue;
-			} else {
-				break;
-			}
-		}
-		req_dequeue = 0;
+		if (info & INFO_ACTIVE)
+			break;
 
 		del_timer(&ept->prime_timer);
 		/* advance ept queue to the next request */
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index 534aa7b..89d2887 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -34,8 +34,8 @@
 
 #define GHSIC_DATA_RMNET_RX_Q_SIZE		50
 #define GHSIC_DATA_RMNET_TX_Q_SIZE		300
-#define GHSIC_DATA_SERIAL_RX_Q_SIZE		2
-#define GHSIC_DATA_SERIAL_TX_Q_SIZE		2
+#define GHSIC_DATA_SERIAL_RX_Q_SIZE		10
+#define GHSIC_DATA_SERIAL_TX_Q_SIZE		20
 #define GHSIC_DATA_RX_REQ_SIZE			2048
 #define GHSIC_DATA_TX_INTR_THRESHOLD		20
 
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index bf3c6d5..037f834 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -93,6 +93,7 @@
 static struct regulator *hsusb_1p8;
 static struct regulator *hsusb_vddcx;
 static struct regulator *vbus_otg;
+static struct regulator *mhl_analog_switch;
 
 static bool aca_id_turned_on;
 static inline bool aca_enabled(void)
@@ -109,7 +110,7 @@
 	int ret = 0;
 
 	if (init) {
-		hsusb_vddcx = regulator_get(motg->otg.dev, "HSUSB_VDDCX");
+		hsusb_vddcx = devm_regulator_get(motg->otg.dev, "HSUSB_VDDCX");
 		if (IS_ERR(hsusb_vddcx)) {
 			dev_err(motg->otg.dev, "unable to get hsusb vddcx\n");
 			return PTR_ERR(hsusb_vddcx);
@@ -121,7 +122,6 @@
 		if (ret) {
 			dev_err(motg->otg.dev, "unable to set the voltage "
 					"for hsusb vddcx\n");
-			regulator_put(hsusb_vddcx);
 			return ret;
 		}
 
@@ -129,7 +129,6 @@
 		if (ret) {
 			regulator_set_voltage(hsusb_vddcx, 0,
 			USB_PHY_VDD_DIG_VOL_MIN);
-			regulator_put(hsusb_vddcx);
 			dev_err(motg->otg.dev, "unable to enable the hsusb vddcx\n");
 			return ret;
 		}
@@ -149,8 +148,6 @@
 					"for hsusb vddcx\n");
 			return ret;
 		}
-
-		regulator_put(hsusb_vddcx);
 	}
 
 	return ret;
@@ -161,7 +158,7 @@
 	int rc = 0;
 
 	if (init) {
-		hsusb_3p3 = regulator_get(motg->otg.dev, "HSUSB_3p3");
+		hsusb_3p3 = devm_regulator_get(motg->otg.dev, "HSUSB_3p3");
 		if (IS_ERR(hsusb_3p3)) {
 			dev_err(motg->otg.dev, "unable to get hsusb 3p3\n");
 			return PTR_ERR(hsusb_3p3);
@@ -172,9 +169,9 @@
 		if (rc) {
 			dev_err(motg->otg.dev, "unable to set voltage level for"
 					"hsusb 3p3\n");
-			goto put_3p3;
+			return rc;
 		}
-		hsusb_1p8 = regulator_get(motg->otg.dev, "HSUSB_1p8");
+		hsusb_1p8 = devm_regulator_get(motg->otg.dev, "HSUSB_1p8");
 		if (IS_ERR(hsusb_1p8)) {
 			dev_err(motg->otg.dev, "unable to get hsusb 1p8\n");
 			rc = PTR_ERR(hsusb_1p8);
@@ -193,11 +190,8 @@
 
 put_1p8:
 	regulator_set_voltage(hsusb_1p8, 0, USB_PHY_1P8_VOL_MAX);
-	regulator_put(hsusb_1p8);
 put_3p3_lpm:
 	regulator_set_voltage(hsusb_3p3, 0, USB_PHY_3P3_VOL_MAX);
-put_3p3:
-	regulator_put(hsusb_3p3);
 	return rc;
 }
 
@@ -314,30 +308,22 @@
 
 static void msm_hsusb_mhl_switch_enable(struct msm_otg *motg, bool on)
 {
-	static struct regulator *mhl_analog_switch;
 	struct msm_otg_platform_data *pdata = motg->pdata;
 
 	if (!pdata->mhl_enable)
 		return;
 
-	if (on) {
-		mhl_analog_switch = regulator_get(motg->otg.dev,
-					       "mhl_ext_3p3v");
-		if (IS_ERR(mhl_analog_switch)) {
-			pr_err("Unable to get mhl_analog_switch\n");
-			return;
-		}
-
-		if (regulator_enable(mhl_analog_switch)) {
-			pr_err("unable to enable mhl_analog_switch\n");
-			goto put_analog_switch;
-		}
+	if (!mhl_analog_switch) {
+		pr_err("%s: mhl_analog_switch is NULL.\n", __func__);
 		return;
 	}
 
-	regulator_disable(mhl_analog_switch);
-put_analog_switch:
-	regulator_put(mhl_analog_switch);
+	if (on) {
+		if (regulator_enable(mhl_analog_switch))
+			pr_err("unable to enable mhl_analog_switch\n");
+	} else {
+		regulator_disable(mhl_analog_switch);
+	}
 }
 
 static int ulpi_read(struct otg_transceiver *otg, u32 reg)
@@ -781,6 +767,7 @@
 	int cnt = 0;
 	bool host_bus_suspend, dcp;
 	u32 phy_ctrl_val = 0, cmd_val;
+	unsigned ret;
 	u32 portsc;
 
 	if (atomic_read(&motg->in_lpm))
@@ -882,7 +869,10 @@
 	clk_disable_unprepare(motg->core_clk);
 
 	/* usb phy no more require TCXO clock, hence vote for TCXO disable */
-	clk_disable_unprepare(motg->xo_handle);
+	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 &&
 			!host_bus_suspend && !dcp) {
@@ -927,7 +917,7 @@
 	wake_lock(&motg->wlock);
 
 	/* Vote for TCXO when waking up the phy */
-	ret = clk_prepare_enable(motg->xo_handle);
+	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);
@@ -1253,7 +1243,7 @@
 	}
 
 	if (!motg->pdata->vbus_power && host) {
-		vbus_otg = regulator_get(motg->otg.dev, "vbus_otg");
+		vbus_otg = devm_regulator_get(motg->otg.dev, "vbus_otg");
 		if (IS_ERR(vbus_otg)) {
 			pr_err("Unable to get vbus_otg\n");
 			return -ENODEV;
@@ -1273,9 +1263,6 @@
 			otg->host = NULL;
 		}
 
-		if (vbus_otg)
-			regulator_put(vbus_otg);
-
 		return 0;
 	}
 
@@ -3270,7 +3257,7 @@
 		goto free_regs;
 	}
 
-	motg->xo_handle = clk_get(&pdev->dev, "xo");
+	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__);
@@ -3278,7 +3265,7 @@
 		goto free_regs;
 	}
 
-	ret = clk_prepare_enable(motg->xo_handle);
+	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);
@@ -3305,6 +3292,15 @@
 		goto free_init_vddcx;
 	}
 
+	if (pdata->mhl_enable) {
+		mhl_analog_switch = devm_regulator_get(motg->otg.dev,
+							"mhl_ext_3p3v");
+		if (IS_ERR(mhl_analog_switch)) {
+			dev_err(&pdev->dev, "Unable to get mhl_analog_switch\n");
+			goto free_ldo_init;
+		}
+	}
+
 	ret = msm_hsusb_ldo_enable(motg, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "hsusb vreg enable failed\n");
@@ -3421,9 +3417,9 @@
 	msm_hsusb_init_vddcx(motg, 0);
 devote_xo_handle:
 	clk_disable_unprepare(motg->pclk);
-	clk_disable_unprepare(motg->xo_handle);
+	msm_xo_mode_vote(motg->xo_handle, MSM_XO_MODE_OFF);
 free_xo_handle:
-	clk_put(motg->xo_handle);
+	msm_xo_put(motg->xo_handle);
 free_regs:
 	iounmap(motg->regs);
 put_pclk:
@@ -3489,7 +3485,7 @@
 
 	clk_disable_unprepare(motg->pclk);
 	clk_disable_unprepare(motg->core_clk);
-	clk_put(motg->xo_handle);
+	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 606d349..b3b4d53 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -35,11 +35,16 @@
 	bool "Support for triple frame buffer"
 	default n
 
+config FB_MSM_MDP_HW
+	bool
+	default n
+
 choice
 	prompt "MDP HW version"
 	default FB_MSM_MDP22
 
 config FB_MSM_MDP22
+	select FB_MSM_MDP_HW
 	bool "MDP HW ver2.2"
 	---help---
 	  Support for MSM MDP HW revision 2.2
@@ -54,6 +59,7 @@
 
 config FB_MSM_MDP303
 	depends on FB_MSM_MDP30
+	select FB_MSM_MDP_HW
 	bool "MDP HW ver3.03"
 	default n
 	---help---
@@ -64,6 +70,7 @@
 
 config FB_MSM_MDP31
 	select FB_MSM_LCDC_HW
+	select FB_MSM_MDP_HW
 	bool "MDP HW ver3.1"
 	---help---
 	  Support for MSM MDP HW revision 3.1
@@ -71,10 +78,17 @@
 
 config FB_MSM_MDP40
 	select FB_MSM_LCDC_HW
+	select FB_MSM_MDP_HW
 	bool "MDP HW ver4.0"
 	---help---
 	  Support for MSM MDP HW revision 4.0
 	  Say Y here if this is msm7x30 variant platform.
+
+config FB_MSM_MDP_NONE
+	bool "MDP HW None"
+	---help---
+	  Say Y here if this is mdm platform.
+
 endchoice
 
 config FB_MSM_EBI2
@@ -885,4 +899,17 @@
 
 endchoice
 
+config FB_MSM_EBI2_EPSON_S1D_QVGA_PANEL
+	bool "EBI2 Epson QVGA Panel"
+	select FB_MSM_EBI2
+	default n
+	---help---
+	  Support for EBI2 Epson QVGA (240x320) panel
+
+config FB_MSM_EBI2_PANEL_DETECT
+	bool "EBI2 Panel Detect"
+	select FB_MSM_EBI2_EPSON_S1D_QVGA_PANEL
+	default n
+	---help---
+	  Support for EBI2 panel auto detect
 endif
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index d6f59aa..90702f3 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -400,6 +400,14 @@
 		mutex_lock(&hdmi_msm_state_mutex);
 		hdmi_msm_state->cec_enabled = true;
 		hdmi_msm_state->cec_logical_addr = 4;
+
+		/* flush CEC queue */
+		hdmi_msm_state->cec_queue_wr = hdmi_msm_state->cec_queue_start;
+		hdmi_msm_state->cec_queue_rd = hdmi_msm_state->cec_queue_start;
+		hdmi_msm_state->cec_queue_full = false;
+		memset(hdmi_msm_state->cec_queue_rd, 0,
+			sizeof(struct hdmi_msm_cec_msg)*CEC_QUEUE_SIZE);
+
 		mutex_unlock(&hdmi_msm_state_mutex);
 		hdmi_msm_cec_init();
 		hdmi_msm_cec_write_logical_addr(
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 7c5a653..dd22f26 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -2472,6 +2472,7 @@
 				__func__, __LINE__,
 			(HDMI_INP_ND(0x011C) & BIT(8)) >> 8,
 			(HDMI_INP_ND(0x011C) & BIT(9)) >> 9);
+			mutex_unlock(&hdcp_auth_state_mutex);
 			goto error;
 		}
 
diff --git a/drivers/video/msm/mddihosti.c b/drivers/video/msm/mddihosti.c
index 4989d35..1a5a3fd 100644
--- a/drivers/video/msm/mddihosti.c
+++ b/drivers/video/msm/mddihosti.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012 Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1874,42 +1874,6 @@
 			MDDI_MSG_ERR("mddi_client_power return %d", ret);
 	}
 
-#if 0
-	switch (mddi_client_capability_pkt.Mfr_Name) {
-	case 0x4474:
-		if ((mddi_client_capability_pkt.Product_Code != 0x8960) &&
-		    (target == DISPLAY_1)) {
-			ret = PRISM_WVGA;
-		}
-		break;
-
-	case 0xD263:
-		if (target == DISPLAY_1)
-			ret = TOSHIBA_VGA_PRIM;
-		else if (target == DISPLAY_2)
-			ret = TOSHIBA_QCIF_SECD;
-		break;
-
-	case 0:
-		if (mddi_client_capability_pkt.Product_Code == 0x8835) {
-			if (target == DISPLAY_1)
-				ret = SHARP_QVGA_PRIM;
-			else if (target == DISPLAY_2)
-				ret = SHARP_128x128_SECD;
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	if ((!client_detection_try) && (ret != TOSHIBA_VGA_PRIM)
-	    && (ret != TOSHIBA_QCIF_SECD)) {
-		/* Not a Toshiba display, so change drive_lo back to default value */
-		mddi_host_reg_out(DRIVE_LO, 0x0032);
-	}
-#endif
-
 #endif
 
 	return mddi_client_id;
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 6c05833..79464bf 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -988,9 +988,6 @@
 		/* DMA update timestamp */
 		mdp_dma2_last_update_time = ktime_get_real();
 		/* let's turn on DMA2 block */
-#if 0
-		mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
-#endif
 #ifdef CONFIG_FB_MSM_MDP22
 		outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x0044, 0x0);/* start DMA */
 #else
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 9d8c205..6ab4edf 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -747,4 +747,5 @@
 
 int mdp4_igc_lut_config(struct mdp_igc_lut_data *cfg);
 void mdp4_iommu_unmap(struct mdp4_overlay_pipe *pipe);
+void mdp4_iommu_attach(void);
 #endif /* MDP_H */
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 36cfd16..a4db73e 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -22,6 +22,7 @@
 #include <linux/clk.h>
 #include <mach/hardware.h>
 #include <mach/iommu_domains.h>
+#include <mach/iommu.h>
 #include <linux/io.h>
 #include <linux/debugfs.h>
 #include <linux/fb.h>
@@ -1454,8 +1455,6 @@
 			pipe_cnt++;
 
 			mdp4_mixer_blend_setup(pipe);
-			if (i == mixer && pipe->pipe_num <= OVERLAY_PIPE_RGB2)
-				flush_bits |= (1 << (2 + pipe->pipe_num));
 		}
 	}
 
@@ -1691,15 +1690,23 @@
 
 void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
 {
+	struct mdp4_overlay_pipe *bg_pipe;
 	uint32 bits = 0;
 
-	if (pipe->mixer_num == MDP4_MIXER1)
-		bits |= 0x02;
-	else
-		bits |= 0x01;
+	if (all) {
+		if (pipe->mixer_num == MDP4_MIXER1)
+			bits |= 0x02;
+		else
+			bits |= 0x01;
+	}
 
-	if (all && pipe->pipe_num <= OVERLAY_PIPE_RGB2)
+	if (pipe->pipe_num <= OVERLAY_PIPE_RGB2)
 		bits |= 1 << (2 + pipe->pipe_num);
+	if (pipe->is_fg && pipe->alpha == 0xFF) {
+		bg_pipe = mdp4_overlay_stage_pipe(pipe->mixer_num,
+						  MDP4_MIXER_STAGE_BASE);
+		bits |= 1 << (2 + bg_pipe->pipe_num);
+	}
 
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 	outpdw(MDP_BASE + 0x18000, bits);	/* MDP_OVERLAY_REG_FLUSH */
@@ -2428,6 +2435,15 @@
 	if (ctrl->panel_mode & MDP4_PANEL_DTV &&
 	    pipe->mixer_num == MDP4_MIXER1) {
 		u32 use_blt = mdp4_overlay_blt_enable(req, mfd, perf_level);
+
+		if (hdmi_prim_display) {
+			if (!mdp4_overlay_is_rgb_type(req->src.format) &&
+				pipe->pipe_type == OVERLAY_TYPE_VIDEO &&
+				(req->src_rect.h > req->dst_rect.h ||
+				req->src_rect.w > req->dst_rect.w))
+				use_blt = 1;
+		}
+
 		mdp4_overlay_dtv_set(mfd, pipe);
 		mfd->use_ov1_blt &= ~(1 << (pipe->pipe_ndx-1));
 		mfd->use_ov1_blt |= (use_blt << (pipe->pipe_ndx-1));
@@ -2813,6 +2829,7 @@
 		/* primary interface */
 		ctrl->mixer0_played++;
 		if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
+			mdp4_overlay_reg_flush(pipe, 0);
 			if (!mfd->use_ov0_blt)
 				mdp4_overlay_update_blt_mode(mfd);
 			mdp4_overlay_lcdc_start();
@@ -2820,6 +2837,7 @@
 		}
 #ifdef CONFIG_FB_MSM_MIPI_DSI
 		else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+			mdp4_overlay_reg_flush(pipe, 0);
 			if (!mfd->use_ov0_blt)
 				mdp4_overlay_update_blt_mode(mfd);
 			mdp4_overlay_dsi_video_start();
@@ -2835,6 +2853,7 @@
 			}
 #ifdef CONFIG_FB_MSM_MIPI_DSI
 			if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+				mdp4_iommu_attach();
 				mdp4_dsi_cmd_dma_busy_wait(mfd);
 				mdp4_dsi_cmd_kickoff_video(mfd, pipe);
 			}
@@ -2868,3 +2887,62 @@
 		fput_light(srcp0_file, ps0_need);
 	return ret;
 }
+
+static struct {
+	char *name;
+	int  domain;
+} msm_iommu_ctx_names[] = {
+	/* Display */
+	{
+		.name = "mdp_vg1",
+		.domain = DISPLAY_DOMAIN,
+	},
+	/* Display */
+	{
+		.name = "mdp_vg2",
+		.domain = DISPLAY_DOMAIN,
+	},
+	/* Display */
+	{
+		.name = "mdp_rgb1",
+		.domain = DISPLAY_DOMAIN,
+	},
+	/* Display */
+	{
+		.name = "mdp_rgb2",
+		.domain = DISPLAY_DOMAIN,
+	},
+};
+
+void mdp4_iommu_attach(void)
+{
+	static int done;
+	struct iommu_domain *domain;
+	int i;
+
+	if (!done) {
+		for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_names); i++) {
+			int domain_idx;
+			struct device *ctx = msm_iommu_get_ctx(
+				msm_iommu_ctx_names[i].name);
+
+			if (!ctx)
+				continue;
+
+			domain_idx = msm_iommu_ctx_names[i].domain;
+
+			domain = msm_get_iommu_domain(domain_idx);
+			if (!domain)
+				continue;
+
+			if (iommu_attach_device(domain,	ctx)) {
+				WARN(1, "%s: could not attach domain %d to context %s."
+					" iommu programming will not occur.\n",
+					__func__, domain_idx,
+					msm_iommu_ctx_names[i].name);
+				continue;
+			}
+		}
+		done = 1;
+	}
+}
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
index f8200a8..dd827aa 100644
--- a/drivers/video/msm/mdp4_overlay_atv.c
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -117,6 +117,8 @@
 
 	mdp4_overlayproc_cfg(pipe);
 
+	mdp4_overlay_reg_flush(pipe, 1);
+
 	if (ret == 0)
 		mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
@@ -184,6 +186,7 @@
 	}
 	mdp4_overlay_rgb_setup(pipe);
 	mdp4_mixer_stage_up(pipe);
+	mdp4_overlay_reg_flush(pipe, 0);
 
 	printk(KERN_INFO "mdp4_atv_overlay: pipe=%x ndx=%d\n",
 					(int)pipe, pipe->pipe_ndx);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 299763f..a5b4b3e 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -672,6 +672,7 @@
 
 		mdp4_overlay_update_dsi_cmd(mfd);
 
+		mdp4_iommu_attach();
 		mdp4_dsi_cmd_kickoff_ui(mfd, dsi_pipe);
 		mdp4_iommu_unmap(dsi_pipe);
 	/* signal if pan function is waiting for the update completion */
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index e729a55..f06f380 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -273,6 +273,7 @@
 	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr);
 	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew);
 	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity);
+	mdp4_overlay_reg_flush(pipe, 1);
 	mdp_histogram_ctrl(TRUE);
 
 	ret = panel_next_on(pdev);
@@ -495,6 +496,7 @@
 {
 	if (!dsi_video_enabled) {
 		/* enable DSI block */
+		mdp4_iommu_attach();
 		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 		MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 1);
 		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 2dd7436..b94d1a4 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -350,6 +350,7 @@
 	}
 
 	mdp4_mixer_stage_up(pipe);
+	mdp4_overlay_reg_flush(pipe, 1);
 
 	dtv_pipe = pipe; /* keep it */
 }
@@ -484,6 +485,7 @@
 void mdp4_overlay_dtv_start(void)
 {
 	if (!dtv_enabled) {
+		mdp4_iommu_attach();
 		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 		/* enable DTV block */
 		MDP_OUTP(MDP_BASE + DTV_BASE, 1);
@@ -560,7 +562,7 @@
 	*/
 	temp_src_format = inpdw(rgb_base + 0x0050);
 	MDP_OUTP(rgb_base + 0x0050, temp_src_format | BIT(22));
-	mdp4_mixer_stage_up(dtv_pipe);
+	mdp4_overlay_reg_flush(dtv_pipe, 0);
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index d9716bd..ed4553d 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -242,6 +242,8 @@
 	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start);
 	MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end);
 
+	mdp4_overlay_reg_flush(pipe, 1);
+
 #ifdef CONFIG_MSM_BUS_SCALING
 	mdp_bus_scale_update_request(2);
 #endif
@@ -396,6 +398,7 @@
 {
 	if (!lcdc_enabled) {
 		/* enable LCDC block */
+		mdp4_iommu_attach();
 		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 		MDP_OUTP(MDP_BASE + LCDC_BASE, 1);
 		mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
diff --git a/drivers/video/msm/mdp_ppp_v20.c b/drivers/video/msm/mdp_ppp_v20.c
index e2a6564..fd04009 100644
--- a/drivers/video/msm/mdp_ppp_v20.c
+++ b/drivers/video/msm/mdp_ppp_v20.c
@@ -2177,26 +2177,8 @@
 			*pppop_reg_ptr |=
 			    (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
 
-		/* let's use SHIM logic to calculate the partial ROI scaling */
-#if 0
-			phasex_step =
-			    (uint32) mdp_do_div(0x20000000 * iBuf->roi.width,
-						dst_roi_width_scale);
-			phasey_step =
-			    (uint32) mdp_do_div(0x20000000 * iBuf->roi.height,
-						dst_roi_height_scale);
-
-/*
-    phasex_step= ((long long) iBuf->roi.width * 0x20000000)/dst_roi_width_scale;
-    phasey_step= ((long long)iBuf->roi.height * 0x20000000)/dst_roi_height_scale;
-*/
-
-			phasex_init =
-			    (((long long)phasex_step - 0x20000000) >> 1);
-			phasey_init =
-			    (((long long)phasey_step - 0x20000000) >> 1);
-
-#else
+			/* let's use SHIM logic to calculate the
+			   partial ROI scaling */
 			mdp_calc_scale_params(iBuf->roi.x, iBuf->roi.width,
 					      dst_roi_width_scale, 1,
 					      &phasex_init, &phasex_step,
@@ -2205,7 +2187,6 @@
 					      dst_roi_height_scale, 0,
 					      &phasey_init, &phasey_step,
 					      &dummy, &dummy);
-#endif
 			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
 				 phasex_init);
 			MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index c826483..dbf45b0 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -39,7 +39,6 @@
 #include "mdp.h"
 #include "mdp4.h"
 
-int mipi_dsi_clk_on;
 static struct completion dsi_dma_comp;
 static struct completion dsi_mdp_comp;
 static struct dsi_buf dsi_tx_buf;
@@ -147,11 +146,6 @@
 
 void mipi_dsi_turn_on_clks(void)
 {
-	if (mipi_dsi_clk_on) {
-		pr_err("%s: mipi_dsi_clks already ON\n", __func__);
-		return;
-	}
-	mipi_dsi_clk_on = 1;
 	local_bh_disable();
 	mipi_dsi_ahb_ctrl(1);
 	mipi_dsi_clk_enable();
@@ -160,11 +154,6 @@
 
 void mipi_dsi_turn_off_clks(void)
 {
-	if (mipi_dsi_clk_on == 0) {
-		pr_err("%s: mipi_dsi_clks already OFF\n", __func__);
-		return;
-	}
-	mipi_dsi_clk_on = 0;
 	local_bh_disable();
 	mipi_dsi_clk_disable();
 	mipi_dsi_ahb_ctrl(0);
diff --git a/drivers/video/msm/msm_dss_io_7x27a.c b/drivers/video/msm/msm_dss_io_7x27a.c
index f17ba0b..193b89c 100644
--- a/drivers/video/msm/msm_dss_io_7x27a.c
+++ b/drivers/video/msm/msm_dss_io_7x27a.c
@@ -30,6 +30,7 @@
 static struct clk *ahb_m_clk;
 static struct clk *ahb_s_clk;
 static struct clk *ebi1_dsi_clk;
+int mipi_dsi_clk_on;
 
 void mipi_dsi_clk_init(struct platform_device *pdev)
 {
@@ -300,14 +301,25 @@
 
 void mipi_dsi_ahb_ctrl(u32 enable)
 {
+	static int ahb_ctrl_done;
 	if (enable) {
+		if (ahb_ctrl_done) {
+			pr_info("%s: ahb clks already ON\n", __func__);
+			return;
+		}
 		clk_enable(dsi_ref_clk);
 		clk_enable(ahb_m_clk);
 		clk_enable(ahb_s_clk);
+		ahb_ctrl_done = 1;
 	} else {
+		if (ahb_ctrl_done == 0) {
+			pr_info("%s: ahb clks already OFF\n", __func__);
+			return;
+		}
 		clk_disable(ahb_m_clk);
 		clk_disable(ahb_s_clk);
 		clk_disable(dsi_ref_clk);
+		ahb_ctrl_done = 0;
 	}
 }
 
@@ -316,6 +328,10 @@
 	unsigned data = 0;
 	uint32 pll_ctrl;
 
+	if (mipi_dsi_clk_on) {
+		pr_info("%s: mipi_dsi_clks already ON\n", __func__);
+		return;
+	}
 	if (clk_set_rate(ebi1_dsi_clk, 65000000)) /* 65 MHz */
 		pr_err("%s: ebi1_dsi_clk set rate failed\n", __func__);
 	clk_enable(ebi1_dsi_clk);
@@ -331,10 +347,15 @@
 	clk_enable(dsi_esc_clk);
 	mipi_dsi_pclk_ctrl(&dsi_pclk, 1);
 	mipi_dsi_clk_ctrl(&dsicore_clk, 1);
+	mipi_dsi_clk_on = 1;
 }
 
 void mipi_dsi_clk_disable(void)
 {
+	if (mipi_dsi_clk_on == 0) {
+		pr_info("%s: mipi_dsi_clks already OFF\n", __func__);
+		return;
+	}
 	mipi_dsi_pclk_ctrl(&dsi_pclk, 0);
 	mipi_dsi_clk_ctrl(&dsicore_clk, 0);
 	clk_disable(dsi_esc_clk);
@@ -345,6 +366,7 @@
 	if (clk_set_rate(ebi1_dsi_clk, 0))
 		pr_err("%s: ebi1_dsi_clk set rate failed\n", __func__);
 	clk_disable(ebi1_dsi_clk);
+	mipi_dsi_clk_on = 0;
 }
 
 void mipi_dsi_phy_ctrl(int on)
diff --git a/drivers/video/msm/msm_dss_io_8960.c b/drivers/video/msm/msm_dss_io_8960.c
index 3f74abd..a6f1d36 100644
--- a/drivers/video/msm/msm_dss_io_8960.c
+++ b/drivers/video/msm/msm_dss_io_8960.c
@@ -62,6 +62,7 @@
 static struct clk *dsi_s_pclk;
 
 static struct clk *amp_pclk;
+int mipi_dsi_clk_on;
 
 static int cont_splash_clks_enabled;
 
@@ -551,22 +552,37 @@
 
 void mipi_dsi_ahb_ctrl(u32 enable)
 {
+	static int ahb_ctrl_done;
 	if (enable) {
+		if (ahb_ctrl_done) {
+			pr_info("%s: ahb clks already ON\n", __func__);
+			return;
+		}
 		clk_enable(amp_pclk); /* clock for AHB-master to AXI */
 		clk_enable(dsi_m_pclk);
 		clk_enable(dsi_s_pclk);
 		mipi_dsi_ahb_en();
 		mipi_dsi_sfpb_cfg();
+		ahb_ctrl_done = 1;
 	} else {
+		if (ahb_ctrl_done == 0) {
+			pr_info("%s: ahb clks already OFF\n", __func__);
+			return;
+		}
 		clk_disable(dsi_m_pclk);
 		clk_disable(dsi_s_pclk);
 		clk_disable(amp_pclk); /* clock for AHB-master to AXI */
+		ahb_ctrl_done = 0;
 	}
 }
 
 void mipi_dsi_clk_enable(void)
 {
 	u32 pll_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0200);
+	if (mipi_dsi_clk_on) {
+		pr_info("%s: mipi_dsi_clks already ON\n", __func__);
+		return;
+	}
 	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pll_ctrl | 0x01);
 	mipi_dsi_phy_rdy_poll();
 
@@ -580,17 +596,23 @@
 	mipi_dsi_clk_ctrl(&dsicore_clk, 1);
 	clk_enable(dsi_byte_div_clk);
 	clk_enable(dsi_esc_clk);
+	mipi_dsi_clk_on = 1;
 	mdp4_stat.dsi_clk_on++;
 }
 
 void mipi_dsi_clk_disable(void)
 {
+	if (mipi_dsi_clk_on == 0) {
+		pr_info("%s: mipi_dsi_clks already OFF\n", __func__);
+		return;
+	}
 	clk_disable(dsi_esc_clk);
 	clk_disable(dsi_byte_div_clk);
 	mipi_dsi_pclk_ctrl(&dsi_pclk, 0);
 	mipi_dsi_clk_ctrl(&dsicore_clk, 0);
 	/* DSIPHY_PLL_CTRL_0, disable dsi pll */
 	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x0);
+	mipi_dsi_clk_on = 0;
 	mdp4_stat.dsi_clk_off++;
 }
 
diff --git a/drivers/video/msm/msm_dss_io_8x60.c b/drivers/video/msm/msm_dss_io_8x60.c
index 7909a92..2231bce 100644
--- a/drivers/video/msm/msm_dss_io_8x60.c
+++ b/drivers/video/msm/msm_dss_io_8x60.c
@@ -32,6 +32,7 @@
 static struct clk *dsi_s_pclk;
 
 static struct clk *amp_pclk;
+int mipi_dsi_clk_on;
 
 void mipi_dsi_clk_init(struct platform_device *pdev)
 {
@@ -396,22 +397,37 @@
 
 void mipi_dsi_ahb_ctrl(u32 enable)
 {
+	static int ahb_ctrl_done;
 	if (enable) {
+		if (ahb_ctrl_done) {
+			pr_info("%s: ahb clks already ON\n", __func__);
+			return;
+		}
 		clk_enable(amp_pclk); /* clock for AHB-master to AXI */
 		clk_enable(dsi_m_pclk);
 		clk_enable(dsi_s_pclk);
 		mipi_dsi_ahb_en();
 		mipi_dsi_sfpb_cfg();
+		ahb_ctrl_done = 1;
 	} else {
+		if (ahb_ctrl_done == 0) {
+			pr_info("%s: ahb clks already OFF\n", __func__);
+			return;
+		}
 		clk_disable(dsi_m_pclk);
 		clk_disable(dsi_s_pclk);
 		clk_disable(amp_pclk); /* clock for AHB-master to AXI */
+		ahb_ctrl_done = 0;
 	}
 }
 
 void mipi_dsi_clk_enable(void)
 {
 	u32 pll_ctrl = MIPI_INP(MIPI_DSI_BASE + 0x0200);
+	if (mipi_dsi_clk_on) {
+		pr_info("%s: mipi_dsi_clks already ON\n", __func__);
+		return;
+	}
 	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, pll_ctrl | 0x01);
 	mb();
 
@@ -421,10 +437,15 @@
 	mipi_dsi_clk_ctrl(&dsicore_clk, 1);
 	clk_enable(dsi_byte_div_clk);
 	clk_enable(dsi_esc_clk);
+	mipi_dsi_clk_on = 1;
 }
 
 void mipi_dsi_clk_disable(void)
 {
+	if (mipi_dsi_clk_on == 0) {
+		pr_info("%s: mipi_dsi_clks already OFF\n", __func__);
+		return;
+	}
 	clk_disable(dsi_esc_clk);
 	clk_disable(dsi_byte_div_clk);
 
@@ -432,6 +453,7 @@
 	mipi_dsi_clk_ctrl(&dsicore_clk, 0);
 	/* DSIPHY_PLL_CTRL_0, disable dsi pll */
 	MIPI_OUTP(MIPI_DSI_BASE + 0x0200, 0x40);
+	mipi_dsi_clk_on = 0;
 }
 
 void mipi_dsi_phy_ctrl(int on)
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index f8cc926..91dc16c 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2187,6 +2187,8 @@
 
 		/* blit first region */
 		if (((splitreq.flags & 0x07) == 0x07) ||
+			((splitreq.flags & 0x07) == 0x05) ||
+			((splitreq.flags & 0x07) == 0x02) ||
 			((splitreq.flags & 0x07) == 0x0)) {
 
 			if (splitreq.flags & MDP_ROT_90) {
@@ -2267,6 +2269,8 @@
 
 		/* blit second region */
 		if (((splitreq.flags & 0x07) == 0x07) ||
+			((splitreq.flags & 0x07) == 0x05) ||
+			((splitreq.flags & 0x07) == 0x02) ||
 			((splitreq.flags & 0x07) == 0x0)) {
 			splitreq.src_rect.h = s_h_1;
 			splitreq.src_rect.y = s_y_1;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 40c5408..d6749e2 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1764,7 +1764,7 @@
 	}
 	memset(output_buf_req, 0,
 		sizeof(struct vcd_buffer_requirement));
-	if (!estimate && !decoder->idr_only_decoding && !decoder->cont_mode)
+	if (!decoder->idr_only_decoding && !decoder->cont_mode)
 		output_buf_req->actual_count = min_dpb + 4;
 	else
 		output_buf_req->actual_count = min_dpb;
diff --git a/include/linux/libra_sdioif.h b/include/linux/libra_sdioif.h
index 99e6f72..99b7d04 100644
--- a/include/linux/libra_sdioif.h
+++ b/include/linux/libra_sdioif.h
@@ -35,6 +35,7 @@
 typedef int (suspend_handler_t)(struct sdio_func *);
 typedef void (resume_handler_t)(struct sdio_func *);
 typedef void (notify_card_removal_t)(void);
+typedef void (shutdown_handler_t)(void);
 
 int libra_enable_sdio_irq_in_chip(struct sdio_func *func, u8 enable);
 int    libra_sdio_configure(sdio_irq_handler_t libra_sdio_rxhandler,
@@ -77,4 +78,6 @@
 int libra_disable_sdio_irq_capability(struct sdio_func *func, u8 disable);
 int libra_sdio_notify_card_removal(
 		notify_card_removal_t *libra_sdio_notify_card_removal_hdlr);
+int libra_sdio_register_shutdown_hdlr(
+		shutdown_handler_t *libra_shutdown_hdlr);
 #endif /* __LIBRA_SDIOIF_H__ */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index dedbe5c..0fcae7c 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -227,7 +227,6 @@
 	struct sdio_cccr	cccr;		/* common card info */
 	struct sdio_cis		cis;		/* common tuple info */
 	struct sdio_func	*sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
-	struct sdio_func	*sdio_single_irq; /* SDIO function when only one IRQ active */
 	unsigned		num_info;	/* number of info strings */
 	const char		**info;		/* info strings */
 	struct sdio_func_tuple	*tuples;	/* unknown common tuples */
diff --git a/include/linux/of.h b/include/linux/of.h
index b904f7e..452ed98 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -249,6 +249,12 @@
 #define for_each_child_of_node(parent, child) \
 	while (0)
 
+static inline int of_device_is_compatible(const struct device_node *device,
+					  const char *name)
+{
+	return 0;
+}
+
 static inline struct property *of_find_property(const struct device_node *np,
 						const char *name,
 						int *lenp)
@@ -288,6 +294,13 @@
 	return NULL;
 }
 
+static inline struct device_node *of_parse_phandle(struct device_node *np,
+						   const char *phandle_name,
+						   int index)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_OF */
 
 static inline int of_property_read_u32(const struct device_node *np,
diff --git a/include/linux/of_slimbus.h b/include/linux/of_slimbus.h
new file mode 100644
index 0000000..8e1dc65
--- /dev/null
+++ b/include/linux/of_slimbus.h
@@ -0,0 +1,34 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slimbus/slimbus.h>
+#include <linux/of_irq.h>
+
+#ifdef CONFIG_OF_SLIMBUS
+/*
+ * of_slim_register_devices() - Register devices in the SLIMbus Device Tree
+ * @ctrl: slim_controller which devices should be registered to.
+ *
+ * This routine scans the SLIMbus Device Tree, allocating resources and
+ * creating slim_devices according to the SLIMbus Device Tree
+ * hierarchy. Details of this hierarchy can be found in
+ * Documentation/devicetree/bindings/slimbus. This routine is normally
+ * called from the probe routine of the driver registering as a
+ * slim_controller.
+ */
+extern int of_register_slim_devices(struct slim_controller *ctrl);
+#else
+static int of_register_slim_devices(struct slim_controller *ctrl)
+{
+	return 0;
+}
+#endif /* CONFIG_OF_SLIMBUS */
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 6c433b8..956a331 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -153,6 +153,7 @@
  * this type.
  *
  * @name: Identifying name for the regulator.
+ * @supply_name: Identifying the regulator supply
  * @id: Numerical identifier for the regulator.
  * @n_voltages: Number of selectors available for ops.list_voltage().
  * @ops: Regulator operations table.
@@ -162,6 +163,7 @@
  */
 struct regulator_desc {
 	const char *name;
+	const char *supply_name;
 	int id;
 	unsigned n_voltages;
 	struct regulator_ops *ops;
@@ -210,7 +212,7 @@
 
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 	struct device *dev, const struct regulator_init_data *init_data,
-	void *driver_data);
+	void *driver_data, struct device_node *of_node);
 void regulator_unregister(struct regulator_dev *rdev);
 
 int regulator_notifier_call_chain(struct regulator_dev *rdev,
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 6804ef3..22a832a 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -95,7 +95,7 @@
  */
 struct regulation_constraints {
 
-	char *name;
+	const char *name;
 
 	/* voltage output range (inclusive) - for voltage control */
 	int min_uV;
diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h
new file mode 100644
index 0000000..d83a98d
--- /dev/null
+++ b/include/linux/regulator/of_regulator.h
@@ -0,0 +1,20 @@
+/*
+ * OpenFirmware regulator support routines
+ *
+ */
+
+#ifndef __LINUX_OF_REG_H
+#define __LINUX_OF_REG_H
+
+#if defined(CONFIG_OF)
+extern struct regulator_init_data
+	*of_get_regulator_init_data(struct device *dev);
+#else
+static inline struct regulator_init_data
+	*of_get_regulator_init_data(struct device *dev)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF */
+
+#endif /* __LINUX_OF_REG_H */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 5845cb6..bb6a01d 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -295,7 +295,7 @@
 	unsigned mA_port;
 	struct timer_list id_timer;
 	unsigned long caps;
-	struct clk *xo_handle;
+	struct msm_xo_voter *xo_handle;
 	uint32_t bus_perf_client;
 	/*
 	 * Allowing PHY power collpase turns off the HSUSB 3.3v and 1.8v
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index 0c7cf8c..822dd69 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -56,8 +56,6 @@
 	int dirty;
 	unsigned int count;
 	void *alloc_ctx;
-	struct msm_mapped_buffer *msm_buffer;
-	int subsys_id;
 	unsigned long mapped_phyaddr;
 	struct ion_handle *ion_handle;
 	struct ion_client *client;
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 0a2849a..ec517b0 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010-2011 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2010-2012 Code Aurora Forum.  All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 and
@@ -115,7 +115,7 @@
 void amp_exit(void);
 
 /* L2CAP-AMP fixed channel interface */
-void amp_conn_ind(struct l2cap_conn *conn, struct sk_buff *skb);
+void amp_conn_ind(struct hci_conn *hcon, struct sk_buff *skb);
 
 /* L2CAP-AMP link interface */
 void amp_create_physical(struct l2cap_conn *conn, struct sock *sk);
@@ -256,7 +256,7 @@
 };
 struct amp_work_conn_ind {
 	struct work_struct work;
-	struct l2cap_conn *conn;
+	struct hci_conn *hcon;
 	struct sk_buff *skb;
 };
 struct amp_work_create_physical {
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d5c4189..b903c5c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -51,7 +51,7 @@
 
 #define L2CAP_CONN_TIMEOUT	(40000) /* 40 seconds */
 #define L2CAP_INFO_TIMEOUT	(4000)  /*  4 seconds */
-#define L2CAP_MOVE_TIMEOUT		(2*HZ)  /*  2 seconds */
+#define L2CAP_MOVE_TIMEOUT		(4*HZ)  /*  4 seconds */
 #define L2CAP_MOVE_ERTX_TIMEOUT		(60*HZ) /* 60 seconds */
 
 /* L2CAP socket address */
diff --git a/kernel/sched.c b/kernel/sched.c
index 1e633e6..f8289fc 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4149,8 +4149,6 @@
  */
 static noinline void __schedule_bug(struct task_struct *prev)
 {
-	struct pt_regs *regs = get_irq_regs();
-
 	printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n",
 		prev->comm, prev->pid, preempt_count());
 
@@ -4158,11 +4156,7 @@
 	print_modules();
 	if (irqs_disabled())
 		print_irqtrace_events(prev);
-
-	if (regs)
-		show_regs(regs);
-	else
-		dump_stack();
+	dump_stack();
 }
 
 /*
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 0a3b91d..df80c42 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010-2011 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2010-2012 Code Aurora Forum.  All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 and
@@ -87,15 +87,15 @@
 	return found;
 }
 
-static struct amp_mgr *get_create_amp_mgr(struct l2cap_conn *conn,
+static struct amp_mgr *get_create_amp_mgr(struct hci_conn *hcon,
 						struct sk_buff *skb)
 {
 	struct amp_mgr *mgr;
 
 	write_lock(&amp_mgr_list_lock);
 	list_for_each_entry(mgr, &amp_mgr_list, list) {
-		if (mgr->l2cap_conn == conn) {
-			BT_DBG("conn %p found %p", conn, mgr);
+		if (mgr->l2cap_conn == hcon->l2cap_data) {
+			BT_DBG("found %p", mgr);
 			write_unlock(&amp_mgr_list_lock);
 			goto gc_finished;
 		}
@@ -106,13 +106,13 @@
 	if (!mgr)
 		return NULL;
 
-	mgr->l2cap_conn = conn;
+	mgr->l2cap_conn = hcon->l2cap_data;
 	mgr->next_ident = 1;
 	INIT_LIST_HEAD(&mgr->ctx_list);
 	rwlock_init(&mgr->ctx_list_lock);
 	mgr->skb = skb;
-	BT_DBG("conn %p mgr %p", conn, mgr);
-	mgr->a2mp_sock = open_fixed_channel(conn->src, conn->dst);
+	BT_DBG("hcon %p mgr %p", hcon, mgr);
+	mgr->a2mp_sock = open_fixed_channel(&hcon->hdev->bdaddr, &hcon->dst);
 	if (!mgr->a2mp_sock) {
 		kfree(mgr);
 		return NULL;
@@ -484,7 +484,7 @@
 	struct amp_ctx *ctx = NULL;
 
 	BT_DBG("conn %p", conn);
-	mgr = get_create_amp_mgr(conn, NULL);
+	mgr = get_create_amp_mgr(conn->hcon, NULL);
 	if (!mgr)
 		goto cp_finished;
 	BT_DBG("mgr %p", mgr);
@@ -514,7 +514,7 @@
 	if (!hdev)
 		goto ap_finished;
 	BT_DBG("hdev %p", hdev);
-	mgr = get_create_amp_mgr(lcon, NULL);
+	mgr = get_create_amp_mgr(lcon->hcon, NULL);
 	if (!mgr)
 		goto ap_finished;
 	BT_DBG("mgr %p", mgr);
@@ -1773,12 +1773,13 @@
 static void conn_ind_worker(struct work_struct *w)
 {
 	struct amp_work_conn_ind *work = (struct amp_work_conn_ind *) w;
-	struct l2cap_conn *conn = work->conn;
+	struct hci_conn *hcon = work->hcon;
 	struct sk_buff *skb = work->skb;
 	struct amp_mgr *mgr;
 
-	mgr = get_create_amp_mgr(conn, skb);
+	mgr = get_create_amp_mgr(hcon, skb);
 	BT_DBG("mgr %p", mgr);
+	hci_conn_put(hcon);
 	kfree(work);
 }
 
@@ -1804,17 +1805,20 @@
 
 /* L2CAP Fixed Channel interface */
 
-void amp_conn_ind(struct l2cap_conn *conn, struct sk_buff *skb)
+void amp_conn_ind(struct hci_conn *hcon, struct sk_buff *skb)
 {
 	struct amp_work_conn_ind *work;
-	BT_DBG("conn %p, skb %p", conn, skb);
+	BT_DBG("hcon %p, skb %p", hcon, skb);
 	work = kmalloc(sizeof(*work), GFP_ATOMIC);
 	if (work) {
 		INIT_WORK((struct work_struct *) work, conn_ind_worker);
-		work->conn = conn;
+		hci_conn_hold(hcon);
+		work->hcon = hcon;
 		work->skb = skb;
-		if (queue_work(amp_workqueue, (struct work_struct *) work) == 0)
+		if (!queue_work(amp_workqueue, (struct work_struct *) work)) {
+			hci_conn_put(hcon);
 			kfree(work);
+		}
 	}
 }
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0ad64a0..739b04c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7361,7 +7361,7 @@
 			bh_unlock_sock(sk);
 		} else if (cid == L2CAP_CID_A2MP) {
 			BT_DBG("A2MP");
-			amp_conn_ind(conn, skb);
+			amp_conn_ind(conn->hcon, skb);
 		} else {
 			BT_DBG("unknown cid 0x%4.4x", cid);
 			kfree_skb(skb);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ddb650b..52c1fe6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2921,7 +2921,7 @@
 
 	if (conn->rssi_update_thresh_exceed == 1) {
 		BT_DBG("rssi_update_thresh_exceed == 1");
-		if (rssi >= conn->rssi_threshold) {
+		if (rssi > conn->rssi_threshold) {
 			memset(&ev, 0, sizeof(ev));
 			bacpy(&ev.bdaddr, bdaddr);
 			ev.rssi = rssi;
@@ -2934,7 +2934,7 @@
 		}
 	} else {
 		BT_DBG("rssi_update_thresh_exceed == 0");
-		if (rssi <= conn->rssi_threshold) {
+		if (rssi < conn->rssi_threshold) {
 			memset(&ev, 0, sizeof(ev));
 			bacpy(&ev.bdaddr, bdaddr);
 			ev.rssi = rssi;
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index c49317c..b65fd65 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -832,7 +832,7 @@
 	ldo->voltage = voltage;
 
 	ldo->dev = regulator_register(&ldo->desc, codec->dev,
-					  init_data, ldo);
+					  init_data, ldo, NULL);
 	if (IS_ERR(ldo->dev)) {
 		int ret = PTR_ERR(ldo->dev);